class FloorplanImageDataConverter:
    def __init__(self):
        pass
    def xy_data_turn(self, x_data, y_data):
        x_data_mins = [item[2] for item in x_data]
        x_data_maxs = [item[4] for item in x_data]
        x_datas = []
        x_datas.extend(x_data_mins)
        x_datas.extend(x_data_maxs)
        _min = min(x_datas)
        _max = max(x_datas)
        diff = _max - _min
        diff_dev = (diff / 2)+_min

        # print(f"x_datas:{x_datas},_min:{_min},_max:{_max},diff:{diff},diff_dev:{diff_dev}")
        new_x_data = []
        new_y_data = []
        for item in x_data:
            xx_start = _max - item[2] + _min
            xx_end = _max - item[4] + _min
            # print(f"item[2]:{item[2]},item[4]:{item[4]},xx_start:{xx_start},xx_end:{xx_end}")
            if item[0]==1:
                new_x_data.append((item[0], item[1], xx_end, item[3], xx_start, item[5]))
            else:
                new_x_data.append((item[0], item[1], xx_end, item[3], xx_start))
        # print(x_data)
        # print(new_x_data)

        for item in y_data:
            xx_start = _max - item[2] + _min
            xx_end = _max - item[4] + _min
            # print(f"item[2]:{item[2]},item[4]:{item[4]},xx_start:{xx_start},xx_end:{xx_end}")
            if item[0]==1:
                new_y_data.append((item[0], item[1], xx_end, item[3], xx_start, item[5]))
            else:
                new_y_data.append((item[0], item[1], xx_end, item[3], xx_start))
        return new_x_data, new_y_data

    def showImg(self, x_data, y_data, gca=True):
        # return
        # print(len(x_data)+len(x_data))
        for line in x_data+y_data:
            index = line[0]
            x1 = line[1]
            y1 = line[2]
            x2 = line[3]
            y2 = line[4]

            # x1 = line[1]
            # y1 = height - line[2]   # 将 y1 调整为从上到下计算
            # x2 = line[3]
            # y2 = height - line[4]   # 将 y2 调整为从上到下计算

            # 根据序号选择颜色
            if index == 0:
                color = 'red'
            # 根据序号选择颜色
            elif index == 1:
                color = 'green'
            elif index == 2:
                color = 'yellow'
            elif index == 3:
                color = 'blue'
            elif index == 4:
                color = 'gold'
            elif index == 5:
                color = 'white'
            # 其他情况直接绘制线条
            plt.plot([x1, x2], [y1, y2], color=color)
        plt.gca().set_aspect('equal', adjustable='box')  # 确保比例一致
        if gca == True:
            plt.gca().invert_yaxis()  # 将y轴翻转，使原点在左上角

        plt.show()

    # #函数遍历
    def data_replace(self, data, x_data_no_point, x_data_has_point):
        for i, o_item in enumerate(data):
            for j, n_item in enumerate(x_data_no_point):
                if o_item == n_item:
                    if j < len(x_data_has_point):  # 检查索引是否在范围内
                        data[i] = x_data_has_point[j]
                        break  # 找到匹配项后退出内循环
        return data

    # x轴计算 tolerance=7
    def update_coordinates_x(self, data, tolerance):
        for i, item in enumerate(data):
            current = item[1]
            for j, item_2 in enumerate(data):
                if j == i:
                    continue
                neighbor = item_2[1]
                if abs(current - neighbor) <= tolerance :
                    # todo : 短墙体 贴合到 长的墙体
                    len1 = abs(item[2]-item[4])
                    len2 = abs(item_2[2]-item_2[4])
                    is_change = False
                    if (len1 >= len2):
                        # 判断断线的中点是否在长线的范围内
                        if self.check_wall_ismyself(item,item_2,tolerance,True):
                            point_new = item[1]
                            is_change = True
                    else:
                        # 判断断线的中点是否在长线的范围内
                        if self.check_wall_ismyself(item_2,item,tolerance,True):
                            point_new = item_2[1]
                            is_change = True
                    # point_new = max(current, neighbor)
                    # print(current,point_new)
                    if is_change:
                        data[i] = (item[0], point_new, item[2], point_new, item[4])
                        data[j] = (item_2[0], point_new,
                                item_2[2], point_new, item_2[4])
                    # print("***")
                    # print(data[i], data[j])
        return data

    # y轴计算 tolerance=7
    def update_coordinates_y(self, data, tolerance):
        for i, item in enumerate(data):
            current = item[2]
            for j, item_2 in enumerate(data):
                if j == i:
                    continue
                neighbor = item_2[2]
                if abs(current - neighbor) <= tolerance:
                    # todo : 短墙体 贴合到 长的墙体
                    len1 = abs(item[1]-item[3])
                    len2 = abs(item_2[1]-item_2[3])
                    is_change = False
                    if (len1 >= len2):
                        # 判断断线的中点是否在长线的范围内
                        if self.check_wall_ismyself(item,item_2,tolerance,False):
                            point_new = item[2]
                            is_change = True
                    else:
                        # 判断断线的中点是否在长线的范围内
                        if self.check_wall_ismyself(item_2,item,tolerance,False):
                            point_new = item_2[2]
                            is_change = True

                    # point_new = max(current, neighbor)
                    # print(current,point_new)
                    if is_change:
                        data[i] = (item[0], item[1], point_new, item[3], point_new)
                        data[j] = (item_2[0], item_2[1],
                                point_new, item_2[3], point_new)
                    # print("***")
                    # print(data[i], data[j])
        return data
    
    # 判断两条墙体线条是否为一个墙体，item为长线条，item_2为短线条
    def check_wall_ismyself(self, item, item_2, tolerance, is_x=True):
        tolerance = (tolerance+2)*2
        is_myself = False
        if is_x:
            # 判断短线条的中点是否在长线条内
            if item[2] <=(item_2[2]+item_2[4])/2<=item[4]:
                is_myself = True
            # 判断线条1的起点 或者终点 是否在线条2附近
            if item_2[2]-tolerance <= item[2] <=item_2[4]+tolerance:
                is_myself = True
            if item_2[2]-tolerance <= item[4] <=item_2[4]+tolerance:
                is_myself = True
        else:
            if item[1] <=(item_2[1]+item_2[3])/2<=item[3]:
                is_myself = True            
            # 判断线条1的起点 或者终点 是否在线条2附近
            if item_2[1]-tolerance <= item[1] <=item_2[3]+tolerance:
                is_myself = True
            if item_2[1]-tolerance <= item[3] <=item_2[3]+tolerance:
                is_myself = True        
        return is_myself

    # 横纵轴就近贴合处理
    def xy_coordinates_convert(self, x1_equals_x2_bboxes, y1_equals_y2_bboxes, tolerance=20):

        # print(x1_equals_x2_bboxes)
        # print(y1_equals_y2_bboxes)

        x_data = self.update_coordinates_x(x1_equals_x2_bboxes, tolerance)
        y_data = self.update_coordinates_y(y1_equals_y2_bboxes, tolerance)

        # print("===>>>>>")
        # print(f"x_data:{x_data},y_data:{y_data}")
        
        x_data = [(line[0],int(line[1]),int(line[2]),int(line[3]),int(line[4])) for line in x_data]
        y_data = [(line[0],int(line[1]),int(line[2]),int(line[3]),int(line[4])) for line in y_data]
        return x_data, y_data

    def xy_startend_convert(self, x_data, y_data, tolerance=5):
        x_data,y_data,x_data_r,y_data_r = self.get_wall_no_point(x_data,y_data)
        # 横轴 起点和终点 对齐纵轴贴合
        x_data_r_old = x_data_r.copy()
        for i, x_point in enumerate(x_data_r):
            # print(x_point[1])
            # 纵轴Y轴起点 对齐横轴X轴贴合
            for j, y_item in enumerate(y_data):
                diff_y1 = abs(x_point[2] - y_item[2])
                # if diff_y1 <= tolerance:                
                # 判断横纵轴贴合，纵轴的线条需要找到横轴最近的线条
                if diff_y1 <= tolerance and y_item[1]-tolerance <= x_point[1] <= y_item[3]+tolerance and y_item[2]<x_point[4]: 
                    x_data_r[i] = x_point[0], x_point[1], y_item[2], x_point[3], x_point[4]
                    # print(f"Y轴diff1:{diff_y1}", x_point[0],x_point[1],y_item[2],x_point[3],x_point[4])
        for i, x_point in enumerate(x_data_r):
            # print(x_point[1])
            # 纵轴Y轴终点 对齐横轴X轴贴合
            for j, y_item in enumerate(y_data):
                diff_y2 = abs(x_point[4] - y_item[2])
                # if diff_y2 <= tolerance:
                # 判断横纵轴贴合，纵轴的线条需要找到横轴最近的线条
                if diff_y2 <= tolerance and y_item[1]-tolerance <= x_point[1] <= y_item[3]+tolerance and x_point[2]<y_item[2]: 
                    x_data_r[i] = x_point[0], x_point[1], x_point[2], x_point[3], y_item[2]
                    # print(f"Y轴diff2:{diff_y2}",   x_point[0],x_point[1],x_point[2],x_point[3],y_item[2])
                # print(y_item)

        y_data_r_old = y_data_r.copy()
        for i, point in enumerate(y_data_r):
            # 横轴X轴起点 对齐纵轴Y轴贴合
            for j, item in enumerate(x_data):
                diff_x1 = abs(point[1] - item[1])
                # if diff_x1 <= tolerance:
                # 判断横纵轴贴合，横轴的线条需要找到纵轴最近的线条
                if diff_x1 <= tolerance and item[2]-tolerance <= point[2] <= item[4]+tolerance and item[1]<point[3]: 
                    y_data_r[i] = point[0], item[1], point[2], point[3], point[4]
        for i, point in enumerate(y_data_r):
            # print(x_point[1])
            # 横轴X轴终点 对齐纵轴Y轴贴合
            for j, item in enumerate(x_data):
                diff_x2 = abs(point[3] - item[1])
                # if diff_x2 <= tolerance:
                # 判断横纵轴贴合，横轴的线条需要找到纵轴最近的线条
                if diff_x2 <= tolerance and item[2]-tolerance <= point[2] <= item[4]+tolerance and point[1]<item[1]: 
                    y_data_r[i] = point[0], point[1], point[2], item[1], point[4]
                # print(y_item)

        x_data = self.data_replace(x_data, x_data_r_old, x_data_r)
        y_data = self.data_replace(y_data, y_data_r_old, y_data_r)  

        y_data = [list(t) for t in set(tuple(line) for line in y_data)]
        x_data = [list(t) for t in set(tuple(line) for line in x_data)]     

        return x_data, y_data

    # 同一水平线 或 垂直线 断线未连接的进行贴合处理
    def xxyy_startend_convert(self, x_data_xy, y_data_xy, tolerance=5):
        # showImg(x_data_xy,y_data_xy)
        for i, point1 in enumerate(y_data_xy):
            # 横轴X轴起点  对齐起终点贴合
            for j, point2 in enumerate(y_data_xy):
                diff_y1 = point1[1] - point2[3]
                if point1[2] == point2[2] and diff_y1 > 0 and diff_y1 <= tolerance:
                    new_start = point1[1]
                    y_data_xy[j] = point2[0], point2[1], point2[2], new_start, point2[4]
        for i, point3 in enumerate(x_data_xy):
            # 横轴X轴起点  对齐起终点贴合
            for j, point4 in enumerate(x_data_xy):
                diff_x1 = point3[2] - point4[4]
                if point3[1] == point4[3] and diff_x1 > 0 and diff_x1 <= tolerance:
                    new_start = point3[2]
                    x_data_xy[j] = point4[0], point4[1], point4[2], point4[3], new_start

        # 排查同一条线收尾相连的情况 diff==0的情况
        for i, line1 in enumerate(y_data_xy):
            for j, line2 in enumerate(y_data_xy):
                # 同一水平线上，起点跟终点重合 或者 终点跟起点重合
                if i != j and line1[2] == line2[2] and (line1[1] == line2[3]):
                    # print(f"line1:{line1},line2:{line2}")
                    y_data_xy[i] = line1[0], line2[1], line1[2], line1[3], line1[4]
                    y_data_xy[j] = line2[0], line2[1], line2[2], line1[3], line2[4]

        for i, line1 in enumerate(x_data_xy):
            for j, line2 in enumerate(x_data_xy):
                # 同一水平线上，起点跟终点重合 或者 终点跟起点重合
                if i != j and line1[1] == line2[1] and (line1[2] == line2[4]):
                    # print(f"line1:{line1},line2:{line2}")
                    x_data_xy[i] = line1[0], line1[1], line2[2], line1[3], line1[4]
                    x_data_xy[j] = line2[0], line2[1], line2[2], line2[3], line1[4]
        # 去重
        y_data_xy1 = [list(t) for t in set(tuple(line) for line in y_data_xy)]
        x_data_xy1 = [list(t) for t in set(tuple(line) for line in x_data_xy)]
        # showImg(x_data_xy1,y_data_xy1)
        return x_data_xy1, y_data_xy1

    # 线条去重，将短线条与长线条重合的，去掉短线条
    def xy_data_remove(self, x_data, y_data):
        # 去重
        y_data = [list(t) for t in set(tuple(line) for line in y_data)]
        x_data = [list(t) for t in set(tuple(line) for line in x_data)]

        # 线条去重，将短线条与长线条重合的，去掉短线条
        y_data_remove = set()  # 使用集合来存储需要移除的线条索引，避免重复
        # print(f"y_data==>{len(y_data)}")
        # 遍历所有的线条，找到需要移除的短线条
        for i, line1 in enumerate(y_data):
            for j, line2 in enumerate(y_data):
                if i != j and line1[2] == line2[2] and ((line1[3] - line1[1]) < (line2[3] - line2[1])) and (line1[1] >= line2[1] and line1[3] <= line2[3]):
                    # print(f"i:{y_data[i]}, j:{y_data[j]}")
                    y_data_remove.add(i)
                    break
        # 从 y_data 中移除 y_data_remove 中的线条
        y_data = [line for idx, line in enumerate(
            y_data) if idx not in y_data_remove]
        # print(f"y_data==>{len(y_data)}")

        # 线条去重，将短线条与长线条重合的，去掉短线条
        x_data_remove = set()  # 使用集合来存储需要移除的线条索引，避免重复
        # print(f"x_data==>{len(x_data)}")
        # 遍历所有线条，找到需要移除的短线条
        for i, line1 in enumerate(x_data):
            for j, line2 in enumerate(x_data):
                if i != j and line1[1] == line2[1] and (line1[4] - line1[2]) < (line2[4] - line2[2]) and (line1[2] >= line2[2] and line1[4] <= line2[4]):
                    # print(f"i:{x_data[i]}, j:{x_data[j]}")
                    x_data_remove.add(i)
                    break
        # 从 x_data 中移除 x_data_remove 中的线条
        x_data = [line for idx, line in enumerate(
            x_data) if idx not in x_data_remove]

        # x_data_remove_lines = [line for idx, line in enumerate(x_data) if idx in x_data_remove]
        # print(f"x_data_remove_lines==>{x_data_remove_lines}")

        # print(f"x_data==>{len(x_data)}")
        # 移除只有点的线条
        y_data = [line for line in y_data if line[3] > line[1]]
        x_data = [line for line in x_data if line[4] > line[2]]
        return x_data, y_data

    # 横纵轴未贴合的线条排查处理
    def xy_check_convert(self, x_data, y_data, tolerance=20):
        # 找到所有水平线条没有跟纵轴交叉的线条
        y_data_remove = set()
        for i, line1 in enumerate(y_data):
            is_ok = False
            for j, line2 in enumerate(x_data):
                if line1[1] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4]:
                    for k, line3 in enumerate(x_data):
                        if line1[3] == line3[1] and line1[2] >= line3[2] and line1[2] <= line3[4]:
                            is_ok = True
            if is_ok == False:
                y_data_remove.add(i)
        y_data_2 = [line for idx, line in enumerate(
            y_data) if idx in y_data_remove]

        # 找到所有垂直线条没有跟纵轴交叉的线条
        x_data_remove = set()
        for i, line1 in enumerate(x_data):
            is_ok = False
            for j, line2 in enumerate(y_data):
                if line1[2] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]:
                    for k, line3 in enumerate(y_data):
                        if line1[4] == line3[2] and line1[1] >= line3[1] and line1[1] <= line3[3]:
                            is_ok = True
            if is_ok == False:
                x_data_remove.add(i)
        x_data_2 = [line for idx, line in enumerate(
            x_data) if idx in x_data_remove]

        # todo: 起点 或者 终点 未靠道墙体的 约等于处理
        # ------x_data-start -----#
        x_data_no_point = []
        x_data_has_point = []
        x_data_no_point2 = []
        x_data_has_point2 = []
        for i, line1 in enumerate(x_data_2):
            # print(f"line1:{line1}")
            is_start = False
            is_end = False
            for j, line2 in enumerate(y_data):
                if line1[2] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]:
                    # print(f"line1:is_start=true")
                    is_start = True
                elif line1[4] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]:
                    # print(f"line1:is_end=true")
                    is_end = True
            if is_start == False:
                # print(f"line1-is_start:{line1}")
                for j, line2 in enumerate(y_data):
                    # diff_l = abs(line1[2]-line2[2])
                    diff_l = (line1[2]-line2[2])
                    # if  diff_l < tolerance and diff_l > 0 and abs(line1[4]-line2[2]) > 0  and line1[1]>= line2[1] and line1[1]<= line2[3]:
                    if diff_l < tolerance and diff_l > 0 and abs(line1[4]-line2[2]) > 0 and line1[1] >= (line2[1]-tolerance) and line1[1] <= (line2[3]+tolerance):
                        x_data_no_point.append(x_data_2[i])
                        newline1 = x_data_2[i][0], x_data_2[i][1], line2[2], x_data_2[i][3], x_data_2[i][4]
                        x_data_2[i] = newline1
                        x_data_has_point.append(newline1)
                    pass
            if is_end == False:
                # print(f"line1-is_end:{line1}")
                for j, line2 in enumerate(y_data):
                    # diff_l = abs(line1[4]-line2[2])
                    diff_l = (line2[2]-line1[4])
                    # if  diff_l < tolerance and diff_l > 0 and abs(line1[2]-line2[2]) > 0  and line1[1]>= line2[1] and line1[1]<= line2[3]:
                    if diff_l < tolerance and diff_l > 0 and abs(line1[2]-line2[2]) > 0 and line1[1] >= (line2[1]-tolerance) and line1[1] <= (line2[3]+tolerance):
                        x_data_no_point2.append(x_data_2[i])
                        newline1 = x_data_2[i][0], x_data_2[i][1], x_data_2[i][2], x_data_2[i][3], line2[2]
                        x_data_2[i] = newline1
                        x_data_has_point2.append(newline1)
                    pass

        # print(f"x_data_no_point:{x_data_no_point}, x_data_has_point:{x_data_has_point}")
        # print(f"x_data_no_point2:{x_data_no_point2}, x_data_has_point2:{x_data_has_point2}")
        x_data = self.data_replace(x_data, x_data_no_point, x_data_has_point)
        x_data = self.data_replace(x_data, x_data_no_point2, x_data_has_point2)
        # -------end -----#

        # ------y_data-start -----#
        y_data_no_point = []
        y_data_has_point = []
        y_data_no_point2 = []
        y_data_has_point2 = []
        for i, line1 in enumerate(y_data_2):
            # print(f"line1:{line1}")
            is_start = False
            is_end = False
            for j, line2 in enumerate(x_data):
                if line1[1] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4]:
                    # print(f"line1:is_start=true")
                    is_start = True
                elif line1[3] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4]:
                    # print(f"line1:is_end=true")
                    is_end = True
            if is_start == False:
                # print(f"line1-is_start:{line1}")
                for j, line2 in enumerate(x_data):
                    # diff_l = abs(line1[1]-line2[1])
                    diff_l = (line1[1]-line2[1])
                    # if  diff_l < tolerance and diff_l > 0 and abs(line1[3]-line2[1]) > 0  and line1[2]>= line2[2] and line1[2]<= line2[4]:
                    if diff_l < tolerance and diff_l > 0 and abs(line1[3]-line2[1]) > 0 and line1[2] >= (line2[2]-tolerance) and line1[2] <= (line2[4]+tolerance):
                        y_data_no_point.append(y_data_2[i])
                        newline1 = y_data_2[i][0], line2[1], y_data_2[i][2], y_data_2[i][3], y_data_2[i][4]
                        y_data_2[i] = newline1
                        y_data_has_point.append(newline1)
                    pass
            if is_end == False:
                # print(f"line1-is_end:{line1}")
                for j, line2 in enumerate(x_data):
                    # diff_l = abs(line1[3]-line2[1])
                    diff_l = (line2[1]-line1[3])
                    # if  diff_l < tolerance and diff_l > 0 and abs(line1[1]-line2[1]) > 0  and line1[2]>= line2[2] and line1[2]<= line2[4]:
                    if diff_l < tolerance and diff_l > 0 and abs(line1[1]-line2[1]) > 0 and line1[2] >= (line2[2]-tolerance) and line1[2] <= (line2[4]+tolerance):
                        y_data_no_point2.append(y_data_2[i])
                        newline1 = y_data_2[i][0], y_data_2[i][1], y_data_2[i][2], line2[1], y_data_2[i][4]
                        y_data_2[i] = newline1
                        y_data_has_point2.append(newline1)
                    pass

        # print(f"y_data_no_point:{y_data_no_point}, y_data_has_point:{y_data_has_point}")
        # print(f"y_data_no_point2:{y_data_no_point2}, y_data_has_point2:{y_data_has_point2}")
        y_data = self.data_replace(y_data, y_data_no_point, y_data_has_point)
        y_data = self.data_replace(y_data, y_data_no_point2, y_data_has_point2)
        # -------end -----#

        # print(f"x_data_2==>{x_data_2}")
        # print(f"y_data_2==>{y_data_2}")

        return x_data, y_data

    # 获取没有闭合的墙体
    def xy_check_point(self, xy_bboxes):
        x_data = []
        y_data = []
        for i, bbox in enumerate(xy_bboxes):
            index, x1, y1, x2, y2 = bbox
            # 如果 x1 = x2，将边界框信息加入 x1_equals_x2_bboxes
            if x1 == x2:
                x_data.append(bbox)

            # 如果 y1 = y2，将边界框信息加入 y1_equals_y2_bboxes
            elif y1 == y2:
                y_data.append(bbox)
            pass

        # 找到所有水平线条没有跟纵轴交叉的线条
        y_data_remove = set()
        for i, line1 in enumerate(y_data):
            is_ok = False
            for j, line2 in enumerate(x_data):
                if line1[1] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4] and line2[4]>line2[2]:
                    for k, line3 in enumerate(x_data):
                        if line1[3] == line3[1] and line1[2] >= line3[2] and line1[2] <= line3[4] and line3[4]>line3[2]:
                            is_ok = True
            if is_ok == False:
                y_data_remove.add(i)
        y_data_2 = [line for idx, line in enumerate(
            y_data) if idx in y_data_remove]

        # 找到所有垂直线条没有跟纵轴交叉的线条
        x_data_remove = set()
        for i, line1 in enumerate(x_data):
            is_ok = False
            for j, line2 in enumerate(y_data):
                if line1[2] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]  and line2[3]>line2[1]:
                    for k, line3 in enumerate(y_data):
                        if line1[4] == line3[2] and line1[1] >= line3[1] and line1[1] <= line3[3] and line3[3]>line3[1]:
                            is_ok = True
            if is_ok == False:
                x_data_remove.add(i)
        x_data_2 = [line for idx, line in enumerate(
            x_data) if idx in x_data_remove]

        # print(f"x_data_2==>{x_data_2}")
        # print(f"y_data_2==>{y_data_2}")
        return x_data_2, y_data_2

    # 移除属于门的多余墙体
    def remove_wallsbydoor(self, x_data, y_data, x_door, y_door, tolerance=5, radio_wall=3, radio_wall_old=1):
        # 找到所有水平线条没有跟纵轴交叉的线条
        # x_data_r, y_data_r = self.xy_check_point(x_data+y_data)
        x_data,y_data,x_data_r,y_data_r = self.get_wall_no_point(x_data,y_data)
        x_line_door_r = []
        y_line_door_r = []
        for i, line1 in enumerate(y_door):
            y_line_door = []
            for j, line3 in enumerate(y_data):
                if abs(line1[2]-line3[2])<=7*radio_wall_old and abs(line1[1]-line3[1])<=7*radio_wall_old and abs(line1[3]-line3[3])<=7*radio_wall_old:
                    y_line_door = line3
                    break
            if len(y_line_door)==0:
                continue
            for j, line2 in enumerate(x_data):
                # if ((y_line_door[1]==line2[1] and y_line_door[2]==line2[2]) or (y_line_door[1]==line2[1] and y_line_door[2]==line2[4])) or ((y_line_door[3]==line2[1] and y_line_door[2]==line2[2]) or (y_line_door[3]==line2[1] and y_line_door[2]==line2[4])):
                if (y_line_door[1]==line2[1] or y_line_door[3]==line2[1]) and (line2[2]==y_line_door[2] or line2[4]==y_line_door[2]) :
                    door_len = line2[4]-line2[2]
                    if door_len<=tolerance:
                        # 门的墙
                        y_line_door_r.append(y_line_door)
                        # 是由于门多补出来的墙体
                        x_line_door_r.append(line2)

        for i, line1 in enumerate(x_door):
            x_line_door = []
            for j, line3 in enumerate(x_data):
                if abs(line1[1]-line3[1])<=7*radio_wall_old and abs(line1[2]-line3[2])<=7*radio_wall_old and abs(line1[4]-line3[4])<=7*radio_wall_old:
                    x_line_door = line3
                    break
            if len(x_line_door)==0:
                continue
            for j, line2 in enumerate(y_data):
                # if ((y_line_door[1]==line2[1] and y_line_door[2]==line2[2]) or (y_line_door[1]==line2[1] and y_line_door[2]==line2[4])) or ((y_line_door[3]==line2[1] and y_line_door[2]==line2[2]) or (y_line_door[3]==line2[1] and y_line_door[2]==line2[4])):
                if (x_line_door[2]==line2[2] or x_line_door[4]==line2[2]) and (line2[1]==x_line_door[1] or line2[3]==x_line_door[1]) :
                    door_len = line2[3]-line2[1]
                    if door_len<=tolerance:
                        # 门的墙
                        x_line_door_r.append(x_line_door)
                        # 是由于门多补出来的墙体
                        y_line_door_r.append(line2)


        x_data = [line for line in x_data if line not in x_line_door_r]
        y_data = [line for line in y_data if line not in y_line_door_r]


        y_data_remove = []
        for i, line1 in enumerate(y_data_r):
            for j, line2 in enumerate(y_door):
                if abs(line1[2]-line2[2]) <= radio_wall and abs(line1[1]-line2[1]) <= tolerance and abs(line1[3]-line2[3]) <= tolerance:
                    y_data_remove.append(line1)
            pass
        pass
        y_data = [line for line in y_data if line not in y_data_remove]

        x_data_remove = []
        # print(x_data_r)
        # print(x_door)
        for i, line1 in enumerate(x_data_r):
            for j, line2 in enumerate(x_door):
                if abs(line1[1]-line2[1]) <= radio_wall and abs(line1[2]-line2[2]) <= tolerance and abs(line1[4]-line2[4]) <= tolerance:
                    x_data_remove.append(line1)
            pass
        pass
        x_data = [line for line in x_data if line not in x_data_remove]
        # print(x_data_remove,y_data_remove)
        return x_data, y_data

    # 寻找门
    def get_door_data(self, x_data, y_data, x_door, y_door, tolerance=5):
        # 找出门的两条线，匹配为一道门
        door_data = []
        for i, line1 in enumerate(y_door):
            for j, line2 in enumerate(x_door):
                if line1[2] >= line2[2]-tolerance and line1[2] <= line2[4]+tolerance and line2[1] >= line1[1]-tolerance and line2[1] <= line1[3]+tolerance:
                    # print(line1,line2)
                    door_data.append((line2, line1))
                    pass
            pass
        pass
        # print(door_data)
        door_x_data_line = []
        door_y_data_line = []
        for i, line1 in enumerate(door_data):
            x_door = line1[0]
            y_door = line1[1]
            x_door_data = []
            y_door_data = []
            for j, line2 in enumerate(x_data):
                x_ycenter = x_door[2] + (x_door[4] - x_door[2])/2
                if abs(x_door[1]-line2[1]) <= tolerance and line2[2] <= x_ycenter <= line2[4]:
                    # 判断开门类型，起点还是终点，朝左还是朝右                    
                    door_isstart = 1             
                    door_isleft = 1
                    # 如果横轴x终点大于纵轴的x,为 终点开门，逆时针开门为左(true)
                    # 横轴终点，在纵轴右侧
                    if y_door[3]>x_door[1]:
                        door_isleft = 0
                        # 横轴终点，在纵轴上侧
                        if y_door[4]>x_door[2]:
                            door_isstart = 1
                        else:
                            door_isstart = 0 
                    else:
                        door_isleft = 1
                        if y_door[4]>x_door[2]:
                            door_isstart = 0
                        else:
                            door_isstart = 1 

                    # 水平翻转问题，需要将纵向的点翻转判断 
                    if door_isstart==0:
                        door_isstart=1
                    else:
                        door_isstart=0

                    x_door_data = (abs(x_door[1]-line2[1]),x_door,line2,(door_isstart,door_isleft))
                    break
            pass
            for j, line2 in enumerate(y_data):
                y_xcenter = x_door[1]+(x_door[3] - x_door[1])/2
                if abs(y_door[2]-line2[2]) <= tolerance and line2[1] <= y_xcenter <= line2[3]:
                    # 判断开门类型，起点还是终点，朝左还是朝右                   
                    door_isstart = 1                
                    door_isleft = 1
                    # 纵轴终点，在横轴上侧
                    if x_door[4]>y_door[2]:
                        door_isleft = 1
                        # 纵轴终点，在横轴右侧
                        if x_door[3]>y_door[1]:
                            door_isstart = 0
                        else:
                            door_isstart = 1
                        pass
                    else:
                        door_isleft = 0
                        # 纵轴终点，在横轴右侧
                        if x_door[3]>y_door[1]:
                            door_isstart = 1
                        else:
                            door_isstart = 0
                        pass
                    pass
                                        
                    # 水平翻转问题，需要将纵向的点翻转判断
                    if door_isleft==0:
                        door_isleft=1
                        if door_isstart==1:
                            door_isstart=0
                        else:
                            door_isstart=1
                    else:
                        door_isleft=0 
                        if door_isstart==1:
                            door_isstart=0
                        else:
                            door_isstart=1
                 
                    y_door_data = (abs(y_door[2]-line2[2]),y_door,line2,(door_isstart,door_isleft))
                    break
            pass
            # print(x_door_data)
            # print(y_door_data)
            # 如果x 更靠近墙体，则x侧是门
            if x_door_data and y_door_data:
                if x_door_data[0] < y_door_data[0]:
                    # 设置门的贴墙线坐标,类型为门的类型,x轴为墙体line2的x，y轴起点终点为x_door的起点终点
                    door_line = x_door_data[1][0], x_door_data[2][1], x_door_data[1][2], x_door_data[2][1], x_door_data[1][4], x_door_data[3]
                    door_x_data_line.append(door_line)
                    pass
                else:
                    # 设置门的贴墙线坐标,类型为门的类型,y轴为墙体line2的y，x轴起点终点为y_door的起点终点
                    door_line = y_door_data[1][0], y_door_data[1][1], y_door_data[2][2], y_door_data[1][3], y_door_data[2][2], y_door_data[3]
                    door_y_data_line.append(door_line)
                    pass
            elif x_door_data:
                # 设置门的贴墙线坐标,类型为门的类型,x轴为墙体line2的x，y轴起点终点为x_door的起点终点
                door_line = x_door_data[1][0], x_door_data[2][1], x_door_data[1][2], x_door_data[2][1], x_door_data[1][4], x_door_data[3]
                door_x_data_line.append(door_line)
                pass
            elif y_door_data:
                # 设置门的贴墙线坐标,类型为门的类型,y轴为墙体line2的y，x轴起点终点为y_door的起点终点
                door_line = y_door_data[1][0], y_door_data[1][1], y_door_data[2][2], y_door_data[1][3], y_door_data[2][2], y_door_data[3]
                door_y_data_line.append(door_line)
                pass

        pass
        # print(door_data)
        # print(door_x_data_line,door_y_data_line)
        return door_x_data_line, door_y_data_line

    def get_wall_no_point(self,x_data,y_data):
        # 找到所有水平线条没有跟纵轴交叉的线条
        x_data_r, y_data_r = self.xy_check_point(x_data+y_data)
        # 找到未封闭的线条，进行分段处理，保证没有跟墙体交叉
        #------ y 处理 start-----------#
        y_data_r_lines = []
        y_data_r_replaces = []
        for i, line1 in enumerate(y_data_r):
            is_start = False
            is_end = False
            for j, line2 in enumerate(x_data):
                # 判断是起点还是终点未闭合
                if line1[1] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4]:
                    is_start = True
                elif line1[3] == line2[1] and line1[2] >= line2[2] and line1[2] <= line2[4]:
                    is_end = True
            y_data_r_m_lines = []
            for j, line2 in enumerate(x_data):
                if line2[2]<=line1[2]<=line2[4] and line1[1]<=line2[1]<=line1[3]:
                    y_data_r_m_lines.append(line2)
            
            if len(y_data_r_m_lines)==0:
                break            
                    
            if is_start == False and is_end:
                # 起点未闭合
                line2_new = y_data_r_m_lines[0]
                for i,line2 in enumerate(y_data_r_m_lines):
                    if line2_new[3]>line2[1]:
                        line2_new = line2
                    pass                
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line2_new[1],line1[4])
                line1_end = (line1[0],line2_new[1],line1[2],line1[3],line1[4])
                y_data_r_lines.append(line1)
                y_data_r_replaces.append(line1_star)
                if line1_end[3]>line1_end[1]:
                    y_data.append(line1_end)
                pass
            elif is_end == False and is_start:
                # 终点未闭合
                line2_new = y_data_r_m_lines[0]
                for i,line2 in enumerate(y_data_r_m_lines):
                    if line2_new[1]<line2[3]:
                        line2_new = line2
                    pass                
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line2_new[1],line1[4])
                line1_end = (line1[0],line2_new[1],line1[2],line1[3],line1[4])
                y_data_r_lines.append(line1)
                y_data_r_replaces.append(line1_end)
                if line1_star[3]>line1_star[1]:
                    y_data.append(line1_star)
                pass
            elif is_start == False and is_end == False:
                # 起点和终点都未闭合
                line2_new = y_data_r_m_lines[0]
                line3_new = y_data_r_m_lines[0]
                for i,line2 in enumerate(y_data_r_m_lines):
                    if line2_new[3]>line2[1]:
                        line2_new = line2
                    pass
                for i,line2 in enumerate(y_data_r_m_lines):
                    if line3_new[1]<line2[3]:
                        line3_new = line2
                    pass              
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line2_new[1],line1[4])
                line1_end = (line1[0],line3_new[1],line1[2],line1[3],line1[4])                
                y_data_r_lines.append(line1)
                y_data_r_replaces.append(line1_star)
                if line1_end[3]>line1_end[1]:
                    y_data.append(line1_end)
                # 被拆分成2段以上，把中间部分加入进去
                if(line3_new[1]>line2_new[1]):
                    line3_startend = (line1[0],line2_new[1],line1[2],line3_new[1],line1[4])
                    y_data.append(line3_startend)
                pass                
        y_data = self.data_replace(y_data, y_data_r_lines, y_data_r_replaces)
        #------ y 处理 end-----------#
        #------ x 处理 start --------#
        x_data_r_lines = []
        x_data_r_replaces = []
        for i, line1 in enumerate(x_data_r):
            is_start = False
            is_end = False
            for j, line2 in enumerate(y_data):
                # 判断是起点还是终点未闭合
                if line1[2] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]:
                    is_start = True
                elif line1[4] == line2[2] and line1[1] >= line2[1] and line1[1] <= line2[3]:
                    is_end = True
            x_data_r_m_lines = []
            for j, line2 in enumerate(y_data):
                if line2[1]<=line1[1]<=line2[3] and line1[2]<=line2[2]<=line1[4]:
                    x_data_r_m_lines.append(line2)
            if len(x_data_r_m_lines)==0:
                break  
                    
            if is_start == False and is_end:
                # 起点未闭合
                line2_new = x_data_r_m_lines[0]
                for i,line2 in enumerate(x_data_r_m_lines):
                    if line2_new[4]>line2[2]:
                        line2_new = line2
                    pass                
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line1[3],line2_new[2])
                line1_end = (line1[0],line1[1],line2_new[2],line1[3],line1[4])
                x_data_r_lines.append(line1)
                x_data_r_replaces.append(line1_star)
                if line1_end[4]>line1_end[2]:
                    x_data.append(line1_end)
                pass
            elif is_end == False and is_start:
                # 终点未闭合
                line2_new = x_data_r_m_lines[0]
                for i,line2 in enumerate(x_data_r_m_lines):
                    if line2_new[2]<line2[4]:
                        line2_new = line2
                    pass                
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line1[3],line2_new[2])
                line1_end = (line1[0],line1[1],line2_new[2],line1[3],line1[4])
                x_data_r_lines.append(line1)
                x_data_r_replaces.append(line1_end)
                if line1_star[4]>line1_star[2]:
                    x_data.append(line1_star)
                pass
            elif is_start == False and is_end == False:
                # 起点和终点都未闭合
                line2_new = x_data_r_m_lines[0]
                line3_new = x_data_r_m_lines[0]
                for i,line2 in enumerate(x_data_r_m_lines):
                    if line2_new[4]>line2[2]:
                        line2_new = line2
                    pass   
                for i,line2 in enumerate(x_data_r_m_lines):
                    if line3_new[2]<line2[4]:
                        line3_new = line2
                    pass               
                # line1被line2_new从中间给截断了
                line1_star = (line1[0],line1[1],line1[2],line1[3],line2_new[2])
                line1_end = (line1[0],line1[1],line3_new[2],line1[3],line1[4])              
                x_data_r_lines.append(line1)
                x_data_r_replaces.append(line1_star)
                if line1_end[4]>line1_end[2]:
                    x_data.append(line1_end)
                # 被拆分成2段以上，把中间部分加入进去
                if(line3_new[2]>line2_new[2]):
                    line3_startend = (line1[0],line1[1],line2_new[2],line1[3],line3_new[2])
                    x_data.append(line3_startend)
                pass                
        x_data = self.data_replace(x_data, x_data_r_lines, x_data_r_replaces)
        #------ x 处理 end --------#
        # 找到所有水平线条没有跟纵轴交叉的线条
        x_data_r, y_data_r = self.xy_check_point(x_data+y_data)
        return x_data,y_data,x_data_r,y_data_r 

    def remove_wall_by_len(self,x_data,y_data,tolerance=10):
        x_data,y_data,x_data_r,y_data_r = self.get_wall_no_point(x_data,y_data)
        x_data_rs = [line for line in x_data_r if (line[4]-line[2])<=tolerance]
        y_data_rs = [line for line in y_data_r if (line[3]-line[1])<=tolerance]

        x_data = [line for line in x_data if line not in x_data_rs]
        y_data = [line for line in y_data if line not in y_data_rs]
        return x_data,y_data


    # 获取窗户的线条
    def get_window_data(self, x_data_win, y_data_win, tolerance=5):
        # 找到所有水平线条没有跟纵轴交叉的线条
        y_data_w_s = []
        y_data_w_ss = []
        for i, line1 in enumerate(y_data_win):
            # 设置窗户类型为3
            line1 = (3, line1[1], line1[2], line1[3], line1[4])
            y_data_w = []
            w = []
            # w = set()
            for j, line2 in enumerate(y_data_win):
                if i != j and abs(line1[2]-line2[2]) <= tolerance and abs(line1[1]-line2[1]) <= tolerance and abs(line1[3]-line2[3]) <= tolerance:
                    # print(line2)
                    w.append(line2)
                    # w.add(line2)
                pass
            pass
            y_data_w = (line1, w)
            # print(f"y_data_w:{y_data_w}")
            is_add = False
            # 防止重复添加
            for k, line3_obj in enumerate(y_data_w_s):
                line3 = line3_obj[0]
                if abs(line1[2]-line3[2]) <= tolerance and abs(line1[1]-line3[1]) <= tolerance and abs(line1[3]-line3[3]) <= tolerance:
                    is_add = True
                    break
            if is_add == False:
                # print(f"==>{y_data_w}")
                y_data_w_s.append(y_data_w)
            pass
        pass

        for i, line1 in enumerate(y_data_w_s):
            if len(line1[1]) >= 3:
                # print(f">{line1}")
                y_data_w_ss.append(line1[0])
            pass

        x_data_w_s = []
        x_data_w_ss = []
        for i, line1 in enumerate(x_data_win):
            line1 = (3, line1[1], line1[2], line1[3], line1[4])
            x_data_w = []
            w = []
            for j, line2 in enumerate(x_data_win):
                if i != j and abs(line1[1]-line2[1]) <= tolerance and abs(line1[2]-line2[2]) <= tolerance and abs(line1[4]-line2[4]) <= tolerance:
                    # print(line2)
                    w.append(line2)
                pass
            pass
            x_data_w = (line1, w)
            # print(f"x_data_w:{x_data_w}")
            is_add = False
            for k, line3_obj in enumerate(x_data_w_s):
                line3 = line3_obj[0]
                if abs(line1[1]-line3[1]) <= tolerance and abs(line1[2]-line3[2]) <= tolerance and abs(line1[4]-line3[4]) <= tolerance:
                    is_add = True
                    break
            if is_add == False:
                # print(f"==>{x_data_w}")
                x_data_w_s.append(x_data_w)
            pass
        pass

        for i, line1 in enumerate(x_data_w_s):
            if len(line1[1]) >= 3:
                # print(f">{line1}")
                x_data_w_ss.append(line1[0])
            pass

        return x_data_w_ss, y_data_w_ss

    # 获取窗户在墙上对应的线条
    def get_windows_line(self, x_data, y_data, x_window, y_window, tolerance=5):
        window_x_data_line = []
        window_y_data_line = []
        for i, line1 in enumerate(x_window):
            for j, line2 in enumerate(x_data):
                if abs(line1[1]-line2[1]) <= tolerance and self.check_wall_ismyself(line1,line2,tolerance,True):
                    # 设置贴墙线坐标,类型类型,x轴为墙体line2的x，y轴起点终点为line1的起点终点
                    window_line = line1[0], line2[1], line1[2], line2[1], line1[4]
                    window_x_data_line.append(window_line)
                    break
            pass
        for i, line1 in enumerate(y_window):
            for j, line2 in enumerate(y_data):
                if abs(line1[2]-line2[2]) <= tolerance and self.check_wall_ismyself(line1,line2,tolerance,False):
                    # 设置贴墙线坐标,类型类型,y轴为墙体line2的y，x轴起点终点为line1起点终点
                    window_line = line1[0], line1[1], line2[2], line1[3], line2[2]
                    window_y_data_line.append(window_line)
                    break
            pass
        pass
        return window_x_data_line, window_y_data_line

    # 移除属于窗的多余墙体
    def remove_wallsbywindow(self, x_data, y_data, x_window, y_window, tolerance=5):
        # 找到所有水平线条没有跟纵轴交叉的线条
        x_data_r, y_data_r = self.xy_check_point(x_data+y_data)
        # print(f"x_window,y_window:{tolerance,x_window,y_window}")
        # print(f"x_data_r,y_data_r:{x_data_r,y_data_r}")
        y_data_remove = []
        for i, line1 in enumerate(y_data_r):
            for j, line2 in enumerate(y_window):
                if abs(line1[2]-line2[2]) <= tolerance and abs(line1[1]-line2[1]) <= tolerance and abs(line1[3]-line2[3]) <= tolerance:
                    y_data_remove.append(line1)
            pass
        pass
        # print(f"y_data_remove:{y_data_remove}")
        y_data = [line for line in y_data if line not in y_data_remove]

        x_data_remove = []
        for i, line1 in enumerate(x_data_r):
            for j, line2 in enumerate(x_window):
                if abs(line1[1]-line2[1]) <= tolerance and abs(line1[2]-line2[2]) <= tolerance and abs(line1[4]-line2[4]) <= tolerance:
                    x_data_remove.append(line1)
            pass
        pass
        # print(f"x_data_remove:{x_data_remove}")
        x_data = [line for line in x_data if line not in x_data_remove]
        # print(x_data_remove,y_data_remove)
        return x_data, y_data

    def move_lines(self, x_data, y_data):
        # # print(x_data)
        _max = 0
        _min = 10000
        for i, line1 in enumerate(y_data):
            if (line1[3] >= _max):
                _max = line1[3]
            if (line1[1] <= _min):
                _min = line1[1]
        x_diff = _max-_min
        x_move = int((_max+_min)/2)        
        x_min = _min

        _max = 0
        _min = 10000
        for i, line1 in enumerate(x_data):
            if (line1[4] >= _max):
                _max = line1[4]
            if (line1[2] <= _min):
                _min = line1[2]
        y_diff = _max-_min
        y_move = int((_max+_min)/2)
        y_min = _min

        for i, line1 in enumerate(y_data):
            if line1[0] == 1:
                y_data[i] = (line1[0], int(line1[1]-x_move), int(line1[2] - y_move), int(line1[3]-x_move), int(line1[4]-y_move), line1[5])
            else:
                y_data[i] = (line1[0], int(line1[1]-x_move), int(line1[2] - y_move), int(line1[3]-x_move), int(line1[4]-y_move))

        for i, line1 in enumerate(x_data):
            if line1[0] == 1:
                x_data[i] = (line1[0], int(line1[1]-x_move), int(line1[2] - y_move), int(line1[3]-x_move), int(line1[4]-y_move), line1[5])
            else:
                x_data[i] = (line1[0], int(line1[1]-x_move), int(line1[2] - y_move), int(line1[3]-x_move), int(line1[4]-y_move))
        return x_data, y_data,(x_move,y_move,(x_min,y_min))

    def get_wall_all_data(self,xy_bboxes,door_tolerance,radio_wall):        
        x1_equals_x2_bboxes =[]
        y1_equals_y2_bboxes = []
        # 门的扇形边长排除
        # door_tolerance = 6

        for i,bbox in  enumerate(xy_bboxes):
            if bbox[0] == 0:
                # print(bbox)
                index, x1, y1, x2, y2 = bbox
                index, x1, y1, x2, y2 =  index, int(x1*radio_wall), int(y1*radio_wall), int(x2*radio_wall), int(y2*radio_wall)
                new_box = index, x1, y1, x2, y2
                # print(index, x1, y1, x2, y2 )
                
                # 如果 x1 = x2，将边界框信息加入 x1_equals_x2_bboxes
                if x1 == x2:
                    if(abs(y1-y2)>door_tolerance*radio_wall):
                        if y1>=y2:
                            new_box = index, x1, y2, x2, y1
                        x1_equals_x2_bboxes.append(new_box)
                
                # 如果 y1 = y2，将边界框信息加入 y1_equals_y2_bboxes
                elif y1 == y2:
                    if(abs(x1-x2)>door_tolerance*radio_wall):
                        if x1>=x2:
                            new_box = index, x2, y1, x1, y2
                        y1_equals_y2_bboxes.append(new_box)
        return x1_equals_x2_bboxes,y1_equals_y2_bboxes

    def get_wall_by_door(self,x_data,y_data,xy_bboxes,door_tolerance,radio_wall):
        # 移除门的弧形：方法 -> 墙-门=真实墙+门的横纵边
        x_data_rem_door = []
        y_data_rem_door = []
        door_remove_width = door_tolerance*radio_wall
        # 获取门的边框数据
        x_door,y_door = self.get_door_all_data(xy_bboxes,0,radio_wall)

        for i,item in enumerate(x_data):
            for j,line in enumerate(x_door+y_door):
                if abs(item[1]-line[1])<=door_remove_width and  abs(item[3]-line[3])<=door_remove_width and abs(item[2]-line[2])<=door_remove_width and abs(item[4]-line[4])<=door_remove_width:
                    x_data_rem_door.append(item)
        for i,item in enumerate(y_data):
            for j,line in enumerate(x_door+y_door):
                if abs(item[1]-line[1])<=door_remove_width and  abs(item[3]-line[3])<=door_remove_width and abs(item[2]-line[2])<=door_remove_width and abs(item[4]-line[4])<=door_remove_width:
                    y_data_rem_door.append(item)
        x_data = [line for line in x_data if line not in x_data_rem_door]
        y_data = [line for line in y_data if line not in y_data_rem_door]        
        # 重新获取门的墙体边数据
        x_door,y_door = self.get_door_all_data(xy_bboxes,12,radio_wall)
        # 进行门的鱼骨架偏移处理
        door_data = []
        # 门的识别画线的线粗是10，所以鱼骨架出来需要便宜的值为5
        add_move_length = 5*radio_wall
        for i, line1 in enumerate(y_door):
            for j, line2 in enumerate(x_door):
                if line1[2] >= line2[2]-door_tolerance*radio_wall and line1[2] <= line2[4]+door_tolerance*radio_wall and line2[1] >= line1[1]-door_tolerance*radio_wall and line2[1] <= line1[3]+door_tolerance*radio_wall:
                    x_start = True
                    y_start = True
                    if abs(line1[3]-line2[3])<door_tolerance*radio_wall:
                        y_start = False
                    if abs(line1[4]-line2[4])<door_tolerance*radio_wall:
                        x_start = False
                    
                    if x_start and y_start:                        
                        y_door[i][2] -= add_move_length
                        y_door[i][4] -= add_move_length
                        x_door[j][1] -= add_move_length
                        x_door[j][3] -= add_move_length
                        # 延长一点
                        y_door[i][1] -= add_move_length                        
                        y_door[i][3] += add_move_length                        
                        x_door[j][2] -= add_move_length                        
                        x_door[j][4] += add_move_length
                    elif x_start and not y_start:
                        y_door[i][2] -= add_move_length
                        y_door[i][4] -= add_move_length
                        x_door[j][1] += add_move_length
                        x_door[j][3] += add_move_length
                        # 延长一点
                        y_door[i][1] -= add_move_length                        
                        y_door[i][3] += add_move_length                        
                        x_door[j][2] -= add_move_length                        
                        x_door[j][4] += add_move_length
                    elif not x_start and  y_start:
                        y_door[i][2] += add_move_length
                        y_door[i][4] += add_move_length
                        x_door[j][1] -= add_move_length
                        x_door[j][3] -= add_move_length
                        # 延长一点
                        y_door[i][1] -= add_move_length                        
                        y_door[i][3] += add_move_length                        
                        x_door[j][2] -= add_move_length                        
                        x_door[j][4] += add_move_length
                    elif not x_start and not y_start:
                        y_door[i][2] += add_move_length
                        y_door[i][4] += add_move_length
                        x_door[j][1] += add_move_length
                        x_door[j][3] += add_move_length
                        # 延长一点
                        y_door[i][1] -= add_move_length                        
                        y_door[i][3] += add_move_length                        
                        x_door[j][2] -= add_move_length                        
                        x_door[j][4] += add_move_length
                    pass
            pass
        pass        
        x_data.extend([(0, line[1], line[2], line[3], line[4]) for line in x_door])
        y_data.extend([(0, line[1], line[2], line[3], line[4]) for line in y_door])
        # 移除只有点的线条
        x_data = [line for line in x_data if (line[4]-line[2])>3*radio_wall]        
        y_data = [line for line in y_data if (line[3]-line[1])>3*radio_wall]

        return x_data,y_data


    def get_door_all_data(self,door_data,door_tolerance,radio_wall):
        x1_equals_x2_bboxes =[]
        y1_equals_y2_bboxes = []
        # 门的扇形边长排除
        # door_tolerance = 10
        # radio_wall = 24.6767
        # radio_wall = 1
        for i,bbox in  enumerate(door_data):
            if bbox[0] == 1:
                # print(bbox)
                index, x1, y1, x2, y2 = bbox
                index, x1, y1, x2, y2 =  index, int(x1*radio_wall), int(y1*radio_wall), int(x2*radio_wall), int(y2*radio_wall)
                new_box = index, x1, y1, x2, y2
                # print(index, x1, y1, x2, y2 )
                
                # 如果 x1 = x2，将边界框信息加入 x1_equals_x2_bboxes
                if x1 == x2:
                    if(abs(y1-y2)>door_tolerance*radio_wall):
                        if y1>=y2:
                            new_box = index, x1, y2, x2, y1
                        x1_equals_x2_bboxes.append(new_box)
                
                # 如果 y1 = y2，将边界框信息加入 y1_equals_y2_bboxes
                elif y1 == y2:
                    if(abs(x1-x2)>door_tolerance*radio_wall):
                        if x1>=x2:
                            new_box = index, x2, y1, x1, y2
                        y1_equals_y2_bboxes.append(new_box)

        # showImg(x1_equals_x2_bboxes,y1_equals_y2_bboxes)
        # print("# 处理门的扇形线条完成================================================================================================================================")
        # print(x1_equals_x2_bboxes,y1_equals_y2_bboxes)
        x_door,y_door = x1_equals_x2_bboxes,y1_equals_y2_bboxes
        # 去重
        x_door = [list(t) for t in set(tuple(line) for line in x_door)]
        y_door = [list(t) for t in set(tuple(line) for line in y_door)]
        return x_door,y_door

    def get_window_all_data(self,xy_bboxes,door_tolerance,radio_wall):
        x1_equals_x2_bboxes =[]
        y1_equals_y2_bboxes = []
      
        # radio_wall = 1
        for i,bbox in  enumerate(xy_bboxes):
            if bbox[0] == 3:
                # print(bbox)
                index, x1, y1, x2, y2 = bbox
                index, x1, y1, x2, y2 =  index, int(x1*radio_wall), int(y1*radio_wall), int(x2*radio_wall), int(y2*radio_wall)
                new_box = index, x1, y1, x2, y2
                # print(index, x1, y1, x2, y2 )
                
                # 如果 x1 = x2，将边界框信息加入 x1_equals_x2_bboxes
                if x1 == x2:
                    x1_equals_x2_bboxes.append(new_box)
                
                # 如果 y1 = y2，将边界框信息加入 y1_equals_y2_bboxes
                elif y1 == y2:
                    y1_equals_y2_bboxes.append(new_box)
        x_door,y_door = x1_equals_x2_bboxes,y1_equals_y2_bboxes
        # 去重
        x_door = [list(t) for t in set(tuple(line) for line in x_door)]
        y_door = [list(t) for t in set(tuple(line) for line in y_door)]
        return x_door,y_door

    def run(self,xy_bboxes,radio_wall,xy_bboxes2):
            x_door,y_door = self.get_door_all_data(xy_bboxes,12,radio_wall)
            x_data,y_data = self.get_wall_all_data(xy_bboxes,0,radio_wall)
            x_data,y_data = self.get_wall_by_door(x_data,y_data,xy_bboxes,10,radio_wall)
            x_data2,y_data2 = self.get_wall_all_data(xy_bboxes2,10,radio_wall)

            self.showImg(xy_bboxes,[])
            self.showImg(x_data,y_data)
            #------  提取窗户 start--------#
            # x_windows_all,y_windows_all =  x_data.copy(),y_data.copy()
            x_windows_all,y_windows_all =  x_data2.copy(),y_data2.copy()
            x_windows,y_windows = self.get_window_data(x_windows_all,y_windows_all,10*radio_wall)

            # x_windows,y_windows = self.get_window_all_data(xy_bboxes,6,radio_wall)

            x_windows_data,y_windows_data = self.xxyy_startend_convert(x_windows,y_windows,2*radio_wall)

            # self.showImg(x_windows_data,y_windows_data)

            # #  # 窗户合并处理
            # windows_x_data_wl_copy,windows_y_data_wl_copy = x_data.copy(),y_data.copy()
            # windows_x_data_wl,windows_y_data_wl = self.xxyy_startend_convert(windows_x_data_wl_copy,windows_y_data_wl_copy,10*radio_wall)
            # x_windows_2,y_windows_2 = self.get_window_data(windows_x_data_wl,windows_y_data_wl,10*radio_wall)
            # self.showImg(x_windows_2,y_windows_2)
            #------  提取窗户 end--------#

            # self.showImg(x_data,y_data)
            # print("# 处理门的扇形线条完成================================================================================================================================")

            # 去重
            x_data = [list(t) for t in set(tuple(line) for line in x_data)]
            y_data = [list(t) for t in set(tuple(line) for line in y_data)]

            # 进行一次贴合操作 5 
            x_data,y_data = self.xy_check_convert(x_data,y_data,5*radio_wall)
            # self.showImg(x_data,y_data)
            
            # 就近贴合处理 10->15
            # 水平贴合，值可以很小5左右
            x_data,y_data = self.xy_coordinates_convert(x_data,y_data,5*radio_wall)
            # self.showImg(x_data,y_data)
            # print("#0 横纵轴就近贴合处理完成======================================================================================================================")

            # # 纵轴 起点和终点 对齐横轴贴合 5
            # 拐角处理贴合，值可以大一点 10-15 左右
            x_data,y_data = self.xy_startend_convert(x_data,y_data,15*radio_wall)
            self.showImg(x_data,y_data)
            # print("#0-1 横轴纵轴 起点和终点 对齐贴合完成=========================================================================================================")

            # 再进行一次贴合操作 30->10
            x_data,y_data = self.xy_check_convert(x_data,y_data,10*radio_wall)
            # 10的间隔 部分无法连接，改为15->13
            x_data,y_data = self.xxyy_startend_convert(x_data,y_data,15*radio_wall)
            self.showImg(x_data,y_data)
            # self.showImg(x_data+x_door,y_data+y_door)
            # print("#0-2 横轴纵轴 同一水平垂直连接 贴合完成=========================================================================================================")

            # 再次同一水平贴合 12 5 10 10 15
            x_data,y_data = self.xy_coordinates_convert(x_data,y_data,5*radio_wall)
            # self.showImg(x_data,y_data)
            x_data,y_data = self.xxyy_startend_convert(x_data,y_data,5*radio_wall)
            # self.showImg(x_data,y_data)
            x_data,y_data = self.xy_coordinates_convert(x_data,y_data,5*radio_wall)
            # self.showImg(x_data,y_data)
            x_data,y_data = self.xxyy_startend_convert(x_data,y_data,10*radio_wall)
            # self.showImg(x_data,y_data)
            x_data,y_data = self.xy_startend_convert(x_data,y_data,10*radio_wall)
            self.showImg(x_data,y_data)
            # self.showImg(x_data,y_data)

            x_data,y_data = self.xy_data_remove(x_data,y_data)
            # self.showImg(x_data,y_data)
            # print("#0-3 线条去重，将短线条与长线条重合,去掉短线条完成=============================================================================================")

            # #------ todo 门合并处理 --------#
            #------  门合并处理 start--------#
            # 移除门开口的偏移处理，5->10, 3->10
            x_data,y_data = self.remove_wallsbydoor(x_data,y_data,x_door,y_door,15*radio_wall,15*radio_wall,radio_wall)
            # self.showImg(x_data,y_data)
            # 门的偏移处理，5 -> 10
            door_x_data_line,door_y_data_line = self.get_door_data(x_data,y_data,x_door,y_door,15*radio_wall)
            # self.showImg(x_data+door_x_data_line,y_data+door_y_data_line)
            #------  门合并处理 end--------#
           
            x_data,y_data = self.xy_check_convert(x_data,y_data,30*radio_wall)

            # self.showImg(x_data,y_data)
            # print("#0-4 去掉 墙体贴合 并 移除未贴合的短线条完成=============================================================================================")


            #------  窗户合并处理 start--------#
            windows_x_data_line,windows_y_data_line = self.get_windows_line(x_data,y_data,x_windows_data,y_windows_data,10*radio_wall)
            # 移除多余的窗户线条
            x_data,y_data = self.remove_wallsbywindow(x_data,y_data,windows_x_data_line,windows_y_data_line,18*radio_wall)
            # 窗户合并处理
            windows_x_data_line_copy,windows_y_data_line_copy = windows_x_data_line.copy(),windows_y_data_line.copy()
            windows_x_data_line_copy,windows_y_data_line_copy = self.xxyy_startend_convert(windows_x_data_line_copy,windows_y_data_line_copy,5*radio_wall)
            # 再次移除多余的窗户线条
            x_data,y_data = self.remove_wallsbywindow(x_data,y_data,windows_x_data_line_copy,windows_y_data_line_copy,15*radio_wall)

            # self.showImg(x_data+door_x_data_line+windows_x_data_line,y_data+door_y_data_line+windows_y_data_line)
            #------  窗户并处理 end--------#

            # 移除小于300mm的没有封闭的墙体，是由于门的误识别造成的
            x_data,y_data = self.remove_wall_by_len(x_data,y_data,5*radio_wall)
            x_data,y_data = self.xy_data_remove(x_data,y_data)
            x_data,y_data = self.xxyy_startend_convert(x_data,y_data,0)
            x_data,y_data = self.xy_data_remove(x_data,y_data)

            x_data,y_data = self.xy_data_turn(x_data+door_x_data_line+windows_x_data_line,y_data+door_y_data_line+windows_y_data_line)

            # self.showImg(x_data,y_data,False)
            # print("#7 坐标翻转处理完成 ===========================================================================================================================")

            # 坐标移动到中心点
            x_data,y_data,move_xy = self.move_lines(x_data,y_data)
            self.showImg(x_data,y_data,False)
            #print("#8 坐标移动处理完成 ===========================================================================================================================")
            return x_data,y_data,move_xy




# 处理门的坐标
# 原图 https://ke-image.ljcdn.com/hdic-frame/standard_014c0ced-3659-405f-b096-663dc56e067f.png!m_fill,w_1000,h_750?from=ke.com
# 线框图 https://vrlab-public.ljcdn.com/release/vrcustomer/outline_0_477d6cbd-9d4f-42cf-b819-4082813fc63a.png
# http://mangoai.dev.com:8820/
# http://mangoai.dev.com:8821/
# https://vrlab-public.ljcdn.com/release/vrcustomer/outline_0_477d6cbd-9d4f-42cf-b819-4082813fc63a.png
# https://vrlab-public.ljcdn.com/release/vrcustomer/outline_0_7ac51d35-f58c-4ece-a0ac-9346424250f1.png
# xy_bboxes = [(0, 166, 452, 167, 451), (0, 167, 451, 265, 451), (0, 265, 451, 266, 452), (0, 266, 452, 264, 454), (0, 264, 454, 168, 454), (0, 168, 454, 166, 452), (0, 72, 451, 73, 450), (0, 73, 450, 163, 450), (0, 163, 450, 164, 451), (0, 164, 451, 161, 454), (0, 161, 454, 75, 454), (0, 75, 454, 72, 451), (0, 167, 448, 168, 447), (0, 168, 447, 268, 447), (0, 268, 447, 269, 448), (0, 269, 448, 269, 449), (0, 269, 449, 267, 451), (0, 267, 451, 165, 451), (0, 165, 451, 164, 450), (0, 164, 450, 164, 449), (0, 164, 449, 165, 448), (0, 165, 448, 167, 448), (0, 78, 447, 163, 447), (0, 163, 447, 164, 448), (0, 164, 448, 164, 449), (0, 164, 449, 163, 450), (0, 163, 450, 77, 450), (0, 77, 450, 76, 449), (0, 76, 449, 78, 447), (0, 37, 273, 38, 272), (0, 38, 272, 120, 272), (0, 120, 272, 123, 275), (0, 123, 275, 123, 279), (0, 123, 279, 124, 280), (0, 124, 280, 124, 282), (0, 124, 282, 125, 283), (0, 125, 283, 125, 285), (0, 125, 285, 126, 286), (0, 126, 286, 126, 287), (0, 126, 287, 128, 289), (0, 128, 289, 128, 290), (0, 128, 290, 137, 299), (0, 137, 299, 138, 299), (0, 138, 299, 139, 300), (0, 139, 300, 140, 300), (0, 140, 300, 141, 301), (0, 141, 301, 143, 301), (0, 143, 301, 144, 302), (0, 144, 302, 146, 302), (0, 146, 302, 147, 303), (0, 147, 303, 153, 303), (0, 153, 303, 154, 302), (0, 154, 302, 154, 274), (0, 154, 274, 156, 272), (0, 156, 272, 163, 272), (0, 163, 272, 164, 273), (0, 164, 273, 164, 446), (0, 164, 446, 163, 447), (0, 163, 447, 78, 447), (0, 78, 447, 75, 450), (0, 75, 450, 71, 450), (0, 71, 450, 70, 449), (0, 70, 449, 70, 423), (0, 70, 423, 69, 422), (0, 69, 422, 38, 422), (0, 38, 422, 37, 421), (0, 37, 421, 37, 273), (0, 120, 272, 121, 271), (0, 121, 271, 154, 271), (0, 154, 271, 155, 272), (0, 155, 272, 155, 273), (0, 155, 273, 154, 274), (0, 154, 274, 154, 302), (0, 154, 302, 153, 303), (0, 153, 303, 147, 303), (0, 147, 303, 146, 302), (0, 146, 302, 144, 302), (0, 144, 302, 143, 301), (0, 143, 301, 141, 301), (0, 141, 301, 140, 300), (0, 140, 300, 139, 300), (0, 139, 300, 138, 299), (0, 138, 299, 137, 299), (0, 137, 299, 128, 290), (0, 128, 290, 128, 289), (0, 128, 289, 126, 287), (0, 126, 287, 126, 286), (0, 126, 286, 125, 285), (0, 125, 285, 125, 283), (0, 125, 283, 124, 282), (0, 124, 282, 124, 280), (0, 124, 280, 123, 279), (0, 123, 279, 123, 275), (0, 123, 275, 120, 272), (0, 112, 192, 113, 191), (0, 113, 191, 114, 192), (0, 114, 192, 114, 223), (0, 114, 223, 113, 224), (0, 113, 224, 112, 223), (0, 112, 223, 108, 223), (0, 108, 223, 107, 222), (0, 107, 222, 104, 222), (0, 104, 222, 103, 221), (0, 103, 221, 101, 221), (0, 101, 221, 100, 220), (0, 100, 220, 99, 220), (0, 99, 220, 98, 219), (0, 98, 219, 97, 219), (0, 97, 219, 88, 210), (0, 88, 210, 88, 209), (0, 88, 209, 86, 207), (0, 86, 207, 86, 206), (0, 86, 206, 85, 205), (0, 85, 205, 85, 204), (0, 85, 204, 84, 203), (0, 84, 203, 84, 201), (0, 84, 201, 83, 200), (0, 83, 200, 83, 197), (0, 83, 197, 82, 196), (0, 82, 196, 82, 193), (0, 82, 193, 83, 192), (0, 83, 192, 112, 192), (0, 37, 186, 38, 185), (0, 38, 185, 113, 185), (0, 113, 185, 114, 186), (0, 114, 186, 114, 190), (0, 114, 190, 112, 192), (0, 112, 192, 83, 192), (0, 83, 192, 82, 193), (0, 82, 193, 82, 196), (0, 82, 196, 83, 197), (0, 83, 197, 83, 200), (0, 83, 200, 84, 201), (0, 84, 201, 84, 203), (0, 84, 203, 85, 204), (0, 85, 204, 85, 205), (0, 85, 205, 86, 206), (0, 86, 206, 86, 207), (0, 86, 207, 88, 209), (0, 88, 209, 88, 210), (0, 88, 210, 97, 219), (0, 97, 219, 98, 219), (0, 98, 219, 99, 220), (0, 99, 220, 100, 220), (0, 100, 220, 101, 221), (0, 101, 221, 103, 221), (0, 103, 221, 104, 222), (0, 104, 222, 107, 222), (0, 107, 222, 108, 223), (0, 108, 223, 112, 223), (0, 112, 223, 114, 225), (0, 114, 225, 114, 271), (0, 114, 271, 113, 272), (0, 113, 272, 38, 272), (0, 38, 272, 37, 271), (0, 37, 271, 37, 186), (0, 148, 154, 149, 153), (0, 149, 153, 154, 153), (0, 154, 153, 155, 154), (0, 155, 154, 155, 184), (0, 155, 184, 154, 185), (0, 154, 185, 124, 185), (0, 124, 185, 123, 184), (0, 123, 184, 123, 183), (0, 123, 183, 124, 182), (0, 124, 182, 124, 180), (0, 124, 180, 125, 179), (0, 125, 179, 125, 176), (0, 125, 176, 126, 175), (0, 126, 175, 126, 173), (0, 126, 173, 127, 172), (0, 127, 172, 127, 171), (0, 127, 171, 128, 170), (0, 128, 170, 128, 169), (0, 128, 169, 129, 168), (0, 129, 168, 129, 167), (0, 129, 167, 132, 164), (0, 132, 164, 132, 163), (0, 132, 163, 135, 160), (0, 135, 160, 136, 160), (0, 136, 160, 138, 158), (0, 138, 158, 139, 158), (0, 139, 158, 140, 157), (0, 140, 157, 141, 157), (0, 141, 157, 142, 156), (0, 142, 156, 143, 156), (0, 143, 156, 144, 155), (0, 144, 155, 145, 155), (0, 145, 155, 146, 154), (0, 146, 154, 148, 154), (0, 232, 118, 233, 117), (0, 233, 117, 234, 117), (0, 234, 117, 235, 118), (0, 235, 118, 235, 148), (0, 235, 148, 234, 149), (0, 234, 149, 204, 149), (0, 204, 149, 203, 148), (0, 203, 148, 203, 144), (0, 203, 144, 204, 143), (0, 204, 143, 204, 141), (0, 204, 141, 205, 140), (0, 205, 140, 205, 138), (0, 205, 138, 206, 137), (0, 206, 137, 206, 136), (0, 206, 136, 207, 135), (0, 207, 135, 207, 134), (0, 207, 134, 209, 132), (0, 209, 132, 209, 131), (0, 209, 131, 216, 124), (0, 216, 124, 217, 124), (0, 217, 124, 219, 122), (0, 219, 122, 220, 122), (0, 220, 122, 221, 121), (0, 221, 121, 222, 121), (0, 222, 121, 223, 120), (0, 223, 120, 225, 120), (0, 225, 120, 226, 119), (0, 226, 119, 229, 119), (0, 229, 119, 230, 118), (0, 230, 118, 232, 118), (0, 249, 79, 250, 78), (0, 250, 78, 283, 78), (0, 283, 78, 285, 80), (0, 285, 80, 285, 82), (0, 285, 82, 284, 83), (0, 284, 83, 284, 109), (0, 284, 109, 283, 110), (0, 283, 110, 278, 110), (0, 278, 110, 277, 109), (0, 277, 109, 274, 109), (0, 274, 109, 273, 108), (0, 273, 108, 271, 108), (0, 271, 108, 270, 107), (0, 270, 107, 269, 107), (0, 269, 107, 266, 104), (0, 266, 104, 265, 104), (0, 265, 104, 260, 99), (0, 260, 99, 260, 98), (0, 260, 98, 258, 96), (0, 258, 96, 258, 95), (0, 258, 95, 256, 93), (0, 256, 93, 256, 92), (0, 256, 92, 255, 91), (0, 255, 91, 255, 89), (0, 255, 89, 254, 88), (0, 254, 88, 254, 86), (0, 254, 86, 253, 85), (0, 253, 85, 253, 83), (0, 253, 83, 249, 79), (0, 237, 78, 248, 78), (0, 248, 78, 253, 83), (0, 253, 83, 253, 85), (0, 253, 85, 254, 86), (0, 254, 86, 254, 88), (0, 254, 88, 255, 89), (0, 255, 89, 255, 91), (0, 255, 91, 256, 92), (0, 256, 92, 256, 93), (0, 256, 93, 258, 95), (0, 258, 95, 258, 96), (0, 258, 96, 260, 98), (0, 260, 98, 260, 99), (0, 260, 99, 265, 104), (0, 265, 104, 266, 104), (0, 266, 104, 269, 107), (0, 269, 107, 270, 107), (0, 270, 107, 271, 108), (0, 271, 108, 273, 108), (0, 273, 108, 274, 109), (0, 274, 109, 277, 109), (0, 277, 109, 278, 110), (0, 278, 110, 283, 110), (0, 283, 110, 284, 109), (0, 284, 109, 284, 83), (0, 284, 83, 286, 81), (0, 286, 81, 287, 81), (0, 287, 81, 289, 79), (0, 289, 79, 290, 79), (0, 290, 79, 291, 78), (0, 291, 78, 302, 78), (0, 302, 78, 303, 79), (0, 303, 79, 303, 389), (0, 303, 389, 302, 390), (0, 302, 390, 269, 390), (0, 269, 390, 302, 390), (0, 302, 390, 303, 391), (0, 303, 391, 303, 436), (0, 303, 436, 302, 437), (0, 302, 437, 270, 437), (0, 270, 437, 269, 438), (0, 269, 438, 269, 446), (0, 269, 446, 268, 447), (0, 268, 447, 168, 447), (0, 168, 447, 167, 448), (0, 167, 448, 165, 448), (0, 165, 448, 164, 447), (0, 164, 447, 164, 389), (0, 164, 389, 165, 388), (0, 165, 388, 179, 388), (0, 179, 388, 165, 388), (0, 165, 388, 164, 387), (0, 164, 387, 164, 273), (0, 164, 273, 163, 272), (0, 163, 272, 155, 272), (0, 155, 272, 154, 271), (0, 154, 271, 121, 271), (0, 121, 271, 120, 272), (0, 120, 272, 115, 272), (0, 115, 272, 114, 271), (0, 114, 271, 114, 225), (0, 114, 225, 115, 224), (0, 115, 224, 116, 224), (0, 116, 224, 115, 224), (0, 115, 224, 114, 223), (0, 114, 223, 114, 186), (0, 114, 186, 115, 185), (0, 115, 185, 154, 185), (0, 154, 185, 155, 184), (0, 155, 184, 157, 184), (0, 157, 184, 158, 185), (0, 158, 185, 166, 185), (0, 166, 185, 167, 186), (0, 167, 186, 167, 219), (0, 167, 219, 166, 220), (0, 166, 220, 167, 219), (0, 167, 219, 167, 157), (0, 167, 157, 168, 156), (0, 168, 156, 234, 156), (0, 234, 156, 235, 155), (0, 235, 155, 235, 152), (0, 235, 152, 234, 151), (0, 234, 151, 234, 149), (0, 234, 149, 235, 148), (0, 235, 148, 235, 80), (0, 235, 80, 237, 78), (0, 106, 79, 107, 78), (0, 107, 78, 134, 78), (0, 134, 78, 135, 79), (0, 135, 79, 132, 82), (0, 132, 82, 107, 82), (0, 107, 82, 106, 81), (0, 106, 81, 106, 79), (0, 79, 79, 80, 78), (0, 80, 78, 105, 78), (0, 105, 78, 106, 79), (0, 106, 79, 106, 81), (0, 106, 81, 105, 82), (0, 105, 82, 82, 82), (0, 82, 82, 79, 79), (0, 39, 78, 78, 78), (0, 78, 78, 82, 82), (0, 82, 82, 132, 82), (0, 132, 82, 135, 79), (0, 135, 79, 137, 79), (0, 137, 79, 138, 78), (0, 138, 78, 164, 78), (0, 164, 78, 167, 81), (0, 167, 81, 167, 155), (0, 167, 155, 168, 156), (0, 168, 156, 167, 157), (0, 167, 157, 167, 184), (0, 167, 184, 166, 185), (0, 166, 185, 158, 185), (0, 158, 185, 157, 184), (0, 157, 184, 156, 184), (0, 156, 184, 155, 183), (0, 155, 183, 155, 154), (0, 155, 154, 154, 153), (0, 154, 153, 149, 153), (0, 149, 153, 148, 154), (0, 148, 154, 146, 154), (0, 146, 154, 145, 155), (0, 145, 155, 144, 155), (0, 144, 155, 143, 156), (0, 143, 156, 142, 156), (0, 142, 156, 141, 157), (0, 141, 157, 140, 157), (0, 140, 157, 139, 158), (0, 139, 158, 138, 158), (0, 138, 158, 136, 160), (0, 136, 160, 135, 160), (0, 135, 160, 132, 163), (0, 132, 163, 132, 164), (0, 132, 164, 129, 167), (0, 129, 167, 129, 168), (0, 129, 168, 128, 169), (0, 128, 169, 128, 170), (0, 128, 170, 127, 171), (0, 127, 171, 127, 172), (0, 127, 172, 126, 173), (0, 126, 173, 126, 175), (0, 126, 175, 125, 176), (0, 125, 176, 125, 179), (0, 125, 179, 124, 180), (0, 124, 180, 124, 182), (0, 124, 182, 123, 183), (0, 123, 183, 123, 184), (0, 123, 184, 122, 185), (0, 122, 185, 38, 185), (0, 38, 185, 37, 184), (0, 37, 184, 37, 80), (0, 37, 80, 39, 78), (0, 107, 76, 108, 75), (0, 108, 75, 132, 75), (0, 132, 75, 134, 77), (0, 134, 77, 133, 78), (0, 133, 78, 108, 78), (0, 108, 78, 107, 77), (0, 107, 77, 107, 76), (0, 84, 75, 106, 75), (0, 106, 75, 107, 76), (0, 107, 76, 107, 77), (0, 107, 77, 106, 78), (0, 106, 78, 83, 78), (0, 83, 78, 82, 77), (0, 82, 77, 84, 75), (0, 165, 57, 166, 56), (0, 166, 56, 167, 56), (0, 167, 56, 168, 57), (0, 168, 57, 168, 66), (0, 168, 66, 166, 68), (0, 166, 68, 165, 67), (0, 165, 67, 165, 57), (0, 161, 57, 162, 56), (0, 162, 56, 164, 56), (0, 164, 56, 165, 57), (0, 165, 57, 165, 67), (0, 165, 67, 164, 68), (0, 164, 68, 161, 65), (0, 161, 65, 161, 57), (0, 165, 44, 166, 43), (0, 166, 43, 168, 45), (0, 168, 45, 168, 55), (0, 168, 55, 167, 56), (0, 167, 56, 166, 56), (0, 166, 56, 165, 55), (0, 165, 55, 165, 44), (0, 163, 43, 164, 43), (0, 164, 43, 165, 44), (0, 165, 44, 165, 55), (0, 165, 55, 164, 56), (0, 164, 56, 162, 56), (0, 162, 56, 161, 55), (0, 161, 55, 161, 45), (0, 161, 45, 163, 43), (0, 165, 39, 166, 38), (0, 166, 38, 236, 38), (0, 236, 38, 237, 39), (0, 237, 39, 237, 78), (0, 237, 78, 235, 80), (0, 235, 80, 235, 116), (0, 235, 116, 234, 117), (0, 234, 117, 233, 117), (0, 233, 117, 232, 118), (0, 232, 118, 230, 118), (0, 230, 118, 229, 119), (0, 229, 119, 226, 119), (0, 226, 119, 225, 120), (0, 225, 120, 223, 120), (0, 223, 120, 222, 121), (0, 222, 121, 221, 121), (0, 221, 121, 220, 122), (0, 220, 122, 219, 122), (0, 219, 122, 217, 124), (0, 217, 124, 216, 124), (0, 216, 124, 209, 131), (0, 209, 131, 209, 132), (0, 209, 132, 207, 134), (0, 207, 134, 207, 135), (0, 207, 135, 206, 136), (0, 206, 136, 206, 137), (0, 206, 137, 205, 138), (0, 205, 138, 205, 140), (0, 205, 140, 204, 141), (0, 204, 141, 204, 143), (0, 204, 143, 203, 144), (0, 203, 144, 203, 148), (0, 203, 148, 204, 149), (0, 204, 149, 233, 149), (0, 233, 149, 234, 150), (0, 234, 150, 234, 151), (0, 234, 151, 235, 152), (0, 235, 152, 235, 155), (0, 235, 155, 234, 156), (0, 234, 156, 168, 156), (0, 168, 156, 167, 155), (0, 167, 155, 167, 81), (0, 167, 81, 164, 78), (0, 164, 78, 165, 77), (0, 165, 77, 165, 69), (0, 165, 69, 168, 66), (0, 168, 66, 168, 45), (0, 168, 45, 165, 42), (0, 165, 42, 165, 39), (0, 166, 38, 165, 39), (0, 165, 39, 165, 42), (0, 165, 42, 164, 43), (0, 164, 43, 163, 43), (0, 163, 43, 161, 45), (0, 161, 45, 161, 65), (0, 161, 65, 165, 69), (0, 165, 69, 165, 77), (0, 165, 77, 164, 78), (0, 164, 78, 138, 78), (0, 138, 78, 137, 79), (0, 137, 79, 136, 79), (0, 136, 79, 132, 75), (0, 132, 75, 84, 75), (0, 84, 75, 81, 78), (0, 81, 78, 39, 78), (0, 39, 78, 37, 80), (0, 37, 80, 37, 421), (0, 37, 421, 38, 422), (0, 38, 422, 69, 422), (0, 69, 422, 70, 423), (0, 70, 423, 70, 449), (0, 70, 449, 75, 454), (0, 75, 454, 161, 454), (0, 161, 454, 164, 451), (0, 164, 451, 165, 451), (0, 165, 451, 168, 454), (0, 168, 454, 264, 454), (0, 264, 454, 269, 449), (0, 269, 449, 269, 438), (0, 269, 438, 270, 437), (0, 270, 437, 302, 437), (0, 302, 437, 303, 436), (0, 303, 436, 303, 79), (0, 303, 79, 302, 78), (0, 302, 78, 291, 78), (0, 291, 78, 290, 79), (0, 290, 79, 289, 79), (0, 289, 79, 287, 81), (0, 287, 81, 286, 81), (0, 286, 81, 283, 78), (0, 283, 78, 238, 78), (0, 238, 78, 237, 77), (0, 237, 77, 237, 39), (0, 237, 39, 236, 38), (0, 236, 38, 166, 38)]
# door_data = [(1, 124, 271, 125, 270), (1, 125, 270, 151, 270), (1, 151, 270, 152, 271), (1, 152, 271, 152, 301), (1, 152, 301, 151, 302), (1, 151, 302, 147, 302), (1, 147, 302, 146, 301), (1, 146, 301, 144, 301), (1, 144, 301, 143, 300), (1, 143, 300, 141, 300), (1, 141, 300, 140, 299), (1, 140, 299, 139, 299), (1, 139, 299, 137, 297), (1, 137, 297, 136, 297), (1, 136, 297, 129, 290), (1, 129, 290, 129, 289), (1, 129, 289, 127, 287), (1, 127, 287, 127, 286), (1, 127, 286, 126, 285), (1, 126, 285, 126, 283), (1, 126, 283, 125, 282), (1, 125, 282, 125, 280), (1, 125, 280, 124, 279), (1, 124, 279, 124, 271), (1, 125, 270, 124, 271), (1, 124, 271, 124, 279), (1, 124, 279, 125, 280), (1, 125, 280, 125, 282), (1, 125, 282, 126, 283), (1, 126, 283, 126, 285), (1, 126, 285, 127, 286), (1, 127, 286, 127, 287), (1, 127, 287, 129, 289), (1, 129, 289, 129, 290), (1, 129, 290, 136, 297), (1, 136, 297, 137, 297), (1, 137, 297, 139, 299), (1, 139, 299, 140, 299), (1, 140, 299, 141, 300), (1, 141, 300, 143, 300), (1, 143, 300, 144, 301), (1, 144, 301, 146, 301), (1, 146, 301, 147, 302), (1, 147, 302, 151, 302), (1, 151, 302, 152, 301), (1, 152, 301, 152, 271), (1, 152, 271, 151, 270), (1, 151, 270, 125, 270), (1, 84, 194, 85, 193), (1, 85, 193, 112, 193), (1, 112, 193, 113, 194), (1, 113, 194, 113, 221), (1, 113, 221, 112, 222), (1, 112, 222, 108, 222), (1, 108, 222, 107, 221), (1, 107, 221, 104, 221), (1, 104, 221, 103, 220), (1, 103, 220, 101, 220), (1, 101, 220, 100, 219), (1, 100, 219, 99, 219), (1, 99, 219, 97, 217), (1, 97, 217, 96, 217), (1, 96, 217, 89, 210), (1, 89, 210, 89, 209), (1, 89, 209, 87, 207), (1, 87, 207, 87, 206), (1, 87, 206, 86, 205), (1, 86, 205, 86, 204), (1, 86, 204, 85, 203), (1, 85, 203, 85, 201), (1, 85, 201, 84, 200), (1, 84, 200, 84, 194), (1, 85, 193, 84, 194), (1, 84, 194, 84, 200), (1, 84, 200, 85, 201), (1, 85, 201, 85, 203), (1, 85, 203, 86, 204), (1, 86, 204, 86, 205), (1, 86, 205, 87, 206), (1, 87, 206, 87, 207), (1, 87, 207, 89, 209), (1, 89, 209, 89, 210), (1, 89, 210, 96, 217), (1, 96, 217, 97, 217), (1, 97, 217, 99, 219), (1, 99, 219, 100, 219), (1, 100, 219, 101, 220), (1, 101, 220, 103, 220), (1, 103, 220, 104, 221), (1, 104, 221, 107, 221), (1, 107, 221, 108, 222), (1, 108, 222, 112, 222), (1, 112, 222, 113, 221), (1, 113, 221, 113, 194), (1, 113, 194, 112, 193), (1, 112, 193, 85, 193), (1, 145, 156, 146, 155), (1, 146, 155, 152, 155), (1, 152, 155, 153, 156), (1, 153, 156, 153, 183), (1, 153, 183, 152, 184), (1, 152, 184, 127, 184), (1, 127, 184, 126, 183), (1, 126, 183, 126, 176), (1, 126, 176, 127, 175), (1, 127, 175, 127, 173), (1, 127, 173, 128, 172), (1, 128, 172, 128, 171), (1, 128, 171, 129, 170), (1, 129, 170, 129, 169), (1, 129, 169, 132, 166), (1, 132, 166, 132, 165), (1, 132, 165, 137, 160), (1, 137, 160, 138, 160), (1, 138, 160, 140, 158), (1, 140, 158, 141, 158), (1, 141, 158, 142, 157), (1, 142, 157, 143, 157), (1, 143, 157, 144, 156), (1, 144, 156, 145, 156), (1, 146, 155, 145, 156), (1, 145, 156, 144, 156), (1, 144, 156, 143, 157), (1, 143, 157, 142, 157), (1, 142, 157, 141, 158), (1, 141, 158, 140, 158), (1, 140, 158, 138, 160), (1, 138, 160, 137, 160), (1, 137, 160, 132, 165), (1, 132, 165, 132, 166), (1, 132, 166, 129, 169), (1, 129, 169, 129, 170), (1, 129, 170, 128, 171), (1, 128, 171, 128, 172), (1, 128, 172, 127, 173), (1, 127, 173, 127, 175), (1, 127, 175, 126, 176), (1, 126, 176, 126, 183), (1, 126, 183, 127, 184), (1, 127, 184, 152, 184), (1, 152, 184, 153, 183), (1, 153, 183, 153, 156), (1, 153, 156, 152, 155), (1, 152, 155, 146, 155), (1, 225, 121, 226, 120), (1, 226, 120, 233, 120), (1, 233, 120, 234, 121), (1, 234, 121, 234, 146), (1, 234, 146, 233, 147), (1, 233, 147, 206, 147), (1, 206, 147, 205, 146), (1, 205, 146, 205, 141), (1, 205, 141, 206, 140), (1, 206, 140, 206, 138), (1, 206, 138, 207, 137), (1, 207, 137, 207, 136), (1, 207, 136, 209, 134), (1, 209, 134, 209, 133), (1, 209, 133, 212, 130), (1, 212, 130, 212, 129), (1, 212, 129, 214, 127), (1, 214, 127, 215, 127), (1, 215, 127, 218, 124), (1, 218, 124, 219, 124), (1, 219, 124, 221, 122), (1, 221, 122, 222, 122), (1, 222, 122, 223, 121), (1, 223, 121, 225, 121), (1, 226, 120, 225, 121), (1, 225, 121, 223, 121), (1, 223, 121, 222, 122), (1, 222, 122, 221, 122), (1, 221, 122, 219, 124), (1, 219, 124, 218, 124), (1, 218, 124, 215, 127), (1, 215, 127, 214, 127), (1, 214, 127, 212, 129), (1, 212, 129, 212, 130), (1, 212, 130, 209, 133), (1, 209, 133, 209, 134), (1, 209, 134, 207, 136), (1, 207, 136, 207, 137), (1, 207, 137, 206, 138), (1, 206, 138, 206, 140), (1, 206, 140, 205, 141), (1, 205, 141, 205, 146), (1, 205, 146, 206, 147), (1, 206, 147, 233, 147), (1, 233, 147, 234, 146), (1, 234, 146, 234, 121), (1, 234, 121, 233, 120), (1, 233, 120, 226, 120), (1, 255, 78, 256, 77), (1, 256, 77, 281, 77), (1, 281, 77, 282, 78), (1, 282, 78, 282, 107), (1, 282, 107, 281, 108), (1, 281, 108, 274, 108), (1, 274, 108, 273, 107), (1, 273, 107, 271, 107), (1, 271, 107, 269, 105), (1, 269, 105, 268, 105), (1, 268, 105, 265, 102), (1, 265, 102, 264, 102), (1, 264, 102, 261, 99), (1, 261, 99, 261, 98), (1, 261, 98, 259, 96), (1, 259, 96, 259, 95), (1, 259, 95, 257, 93), (1, 257, 93, 257, 92), (1, 257, 92, 256, 91), (1, 256, 91, 256, 89), (1, 256, 89, 255, 88), (1, 255, 88, 255, 86), (1, 255, 86, 254, 85), (1, 254, 85, 254, 81), (1, 254, 81, 255, 80), (1, 255, 80, 255, 78), (1, 256, 77, 255, 78), (1, 255, 78, 255, 80), (1, 255, 80, 254, 81), (1, 254, 81, 254, 85), (1, 254, 85, 255, 86), (1, 255, 86, 255, 88), (1, 255, 88, 256, 89), (1, 256, 89, 256, 91), (1, 256, 91, 257, 92), (1, 257, 92, 257, 93), (1, 257, 93, 259, 95), (1, 259, 95, 259, 96), (1, 259, 96, 261, 98), (1, 261, 98, 261, 99), (1, 261, 99, 264, 102), (1, 264, 102, 265, 102), (1, 265, 102, 268, 105), (1, 268, 105, 269, 105), (1, 269, 105, 271, 107), (1, 271, 107, 273, 107), (1, 273, 107, 274, 108), (1, 274, 108, 281, 108), (1, 281, 108, 282, 107), (1, 282, 107, 282, 78), (1, 282, 78, 281, 77), (1, 281, 77, 256, 77)]

import matplotlib.pyplot as plt
import numpy as np
from io import BytesIO
import base64
import json
import math

if __name__ == '__main__': 
    # url: https://ke-image.ljcdn.com/hdic-frame/standard_96bd87f6-d5fd-4fa0-b300-d96ed7cb0c89.png.1440x1080.jpg?from=ke.com
    # ->
    # https://ke-image.ljcdn.com/hdic-frame/standard_xxx.png.1000x750.jpg?from=ke.com
    # https://vrlab-public.ljcdn.com/release/vrcustomer/hierarchy_0_xxx.png    
    # todo: url 获取 线框坐标all_data
      
    xy_bboxes= [(0, 235, 288, 236, 287), (0, 236, 287, 333, 287), (0, 333, 287, 334, 288), (0, 334, 288, 334, 482), (0, 334, 482, 333, 483), (0, 333, 483, 195, 483), (0, 195, 483, 193, 481), (0, 193, 481, 193, 315), (0, 193, 315, 195, 313), (0, 195, 313, 196, 313), (0, 196, 313, 202, 319), (0, 202, 319, 204, 319), (0, 204, 319, 205, 318), (0, 205, 318, 211, 318), (0, 211, 318, 212, 317), (0, 212, 317, 214, 317), (0, 214, 317, 215, 316), (0, 215, 316, 216, 316), (0, 216, 316, 218, 314), (0, 218, 314, 219, 314), (0, 219, 314, 227, 306), (0, 227, 306, 227, 305), (0, 227, 305, 229, 303), (0, 229, 303, 229, 302), (0, 229, 302, 230, 301), (0, 230, 301, 230, 300), (0, 230, 300, 231, 299), (0, 231, 299, 231, 296), (0, 231, 296, 232, 295), (0, 232, 295,232, 290), (0, 232, 290, 234, 288), (0, 234, 288, 235, 288), (0, 203, 287, 232, 287), (0, 232, 287, 233, 288), (0, 233, 288, 233, 289), (0, 233, 289, 232, 290), (0, 232, 290, 232, 295), (0, 232, 295, 231, 296), (0, 231, 296, 231, 299), (0, 231, 299, 230, 300), (0, 230, 300, 230, 301), (0, 230, 301, 229, 302), (0, 229, 302, 229, 303), (0, 229, 303, 227, 305), (0, 227, 305, 227, 306), (0, 227, 306, 219, 314), (0, 219, 314, 218, 314), (0, 218, 314, 216, 316), (0, 216, 316, 215, 316), (0, 215, 316, 214, 317), (0, 214, 317, 212, 317), (0, 212, 317, 211, 318), (0, 211, 318, 205, 318), (0, 205, 318, 204, 319), (0, 204, 319, 202, 319), (0, 202, 319, 195, 312), (0, 195, 312, 195, 295), (0, 195, 295, 203, 287), (0, 286, 251, 287, 250), (0,287, 250, 333, 250), (0, 333, 250, 334, 251), (0, 334, 251, 334, 286), (0, 334, 286, 333, 287), (0, 333, 287, 238, 287), (0, 238, 287, 237, 286), (0, 237, 286, 237, 253), (0, 237, 253, 238, 252), (0, 238, 252, 284, 252), (0, 284, 252, 285, 251), (0, 285, 251, 286, 251), (0, 44, 244, 45, 243), (0, 45, 243, 49, 247), (0, 49, 247, 52, 247), (0, 52, 247, 53, 248), (0, 53, 248, 55, 248), (0, 55, 248, 56, 249), (0, 56, 249, 57, 249), (0, 57, 249, 58, 250), (0, 58, 250, 59, 250), (0, 59, 250, 60, 251), (0, 60, 251, 61, 251), (0, 61, 251, 63, 253), (0, 63, 253, 64, 253), (0, 64, 253, 71, 260), (0, 71, 260, 71, 261), (0, 71, 261, 73, 263), (0, 73, 263, 73, 265), (0, 73, 265, 74, 266), (0, 74, 266, 74, 267), (0, 74, 267, 75, 268), (0, 75, 268, 75, 271), (0, 75, 271, 76, 272), (0, 76, 272, 76, 277), (0, 76, 277, 75, 278), (0, 75, 278, 50, 278), (0, 50, 278, 47, 281), (0, 47, 281, 45, 281), (0, 45, 281, 44, 280), (0, 44, 280, 44, 244), (0, 203, 207, 209, 207), (0, 209, 207, 210, 208), (0, 210, 208, 212, 208), (0, 212, 208, 213, 209), (0, 213, 209, 214, 209), (0, 214, 209, 215, 210), (0, 215, 210, 216, 210), (0, 216, 210, 218, 212), (0, 218, 212, 219, 212), (0, 219, 212, 228, 221), (0, 228, 221, 228, 222), (0, 228, 222, 229, 223), (0, 229, 223, 229, 224), (0, 229, 224, 230, 225), (0, 230, 225, 230, 226), (0, 230, 226, 231,227), (0, 231, 227, 231, 230), (0, 231, 230, 232, 231), (0, 232, 231, 232, 236), (0, 232, 236, 233, 237), (0, 233, 237, 232, 238), (0, 232, 238, 202, 238), (0, 202, 238, 201, 237), (0, 201, 237, 201, 209), (0, 201, 209, 203, 207), (0, 47, 97, 100, 97), (0, 100, 97, 101, 98), (0, 101, 98, 101, 111), (0, 101, 111, 102, 112), (0, 102, 112, 102, 146), (0, 102, 146, 101, 147), (0, 101, 147, 101, 148), (0, 101, 148, 100, 149), (0, 100, 149, 100,181), (0, 100, 181, 99, 182), (0, 99, 182, 45, 182), (0, 45, 182, 44, 181), (0, 44, 181, 44, 100), (0, 44, 100, 47, 97), (0, 101, 97, 102, 96), (0,102, 96, 127, 96), (0, 127, 96, 129, 98), (0, 129, 98, 153, 98), (0, 153, 98, 154, 97), (0, 154, 97, 190, 97), (0, 190, 97, 191, 98), (0, 191, 98, 191, 237), (0, 191, 237, 192, 238), (0, 192, 238, 199, 238), (0, 199, 238, 200, 237), (0, 200, 237, 201, 237), (0, 201, 237, 202, 238), (0, 202, 238, 235, 238), (0, 235, 238, 237, 240), (0, 237, 240, 237, 286), (0, 237, 286, 235, 288), (0, 235, 288, 233, 288), (0, 233, 288, 232, 287), (0, 232, 287, 203, 287), (0, 203, 287, 196, 294), (0, 196, 294, 195, 294), (0, 195, 294, 194, 293), (0, 194, 293, 194, 291), (0, 194, 291, 192, 289), (0, 192,289, 46, 289), (0, 46, 289, 45, 288), (0, 45, 288, 45, 284), (0, 45, 284, 46, 283), (0, 46, 283, 46, 282), (0, 46, 282, 50, 278), (0, 50, 278, 75, 278), (0, 75, 278, 76, 277), (0, 76, 277, 76, 272), (0, 76, 272, 75, 271), (0, 75, 271, 75, 268), (0, 75, 268, 74, 267), (0, 74, 267, 74, 266), (0, 74, 266, 73, 265), (0, 73, 265, 73, 263), (0, 73, 263, 71, 261), (0, 71, 261, 71, 260), (0, 71, 260, 64, 253), (0, 64, 253, 63, 253), (0, 63, 253, 61, 251), (0, 61, 251, 60, 251), (0, 60, 251, 59, 250), (0, 59, 250, 58, 250), (0, 58, 250, 57, 249), (0, 57, 249, 56, 249), (0, 56, 249, 55, 248), (0, 55, 248, 53, 248), (0, 53, 248, 52, 247), (0, 52, 247, 49, 247), (0, 49, 247, 44, 242), (0, 44, 242, 44, 183), (0, 44, 183, 45, 182), (0, 45, 182, 101, 182), (0, 101, 182, 100, 181), (0, 100, 181, 100, 149), (0, 100, 149, 101, 148), (0, 101, 148, 101, 147), (0, 101, 147, 102, 146), (0, 102, 146, 102, 112), (0, 102, 112, 101, 111), (0, 101, 111, 101, 97), (0, 192, 95, 193, 94), (0, 193, 94, 332, 94), (0, 332, 94, 334, 96), (0, 334, 96, 334, 249), (0, 334, 249, 333, 250), (0, 333, 250, 287, 250), (0, 287, 250, 286, 251), (0, 286, 251, 285, 251), (0, 285, 251, 284, 252), (0, 284, 252, 238, 252), (0, 238, 252, 237, 251), (0, 237, 251, 237, 240), (0, 237, 240, 235, 238), (0, 235, 238, 234, 238), (0, 234, 238, 232, 236), (0, 232, 236, 232, 231), (0, 232, 231, 231, 230), (0, 231, 230, 231, 227), (0, 231, 227, 230, 226), (0, 230, 226, 230, 225), (0, 230, 225, 229, 224), (0, 229, 224, 229, 223), (0, 229, 223, 228, 222), (0, 228, 222, 228, 221), (0, 228, 221, 219, 212), (0, 219, 212, 218, 212), (0, 218, 212, 216, 210), (0, 216,210, 215, 210), (0, 215, 210, 214, 209), (0, 214, 209, 213, 209), (0, 213, 209, 212, 208), (0, 212, 208, 210, 208), (0, 210, 208, 209, 207), (0, 209, 207, 203, 207), (0, 203, 207, 201, 209), (0, 201, 209, 201, 236), (0, 201, 236, 199, 238), (0, 199, 238, 192, 238), (0, 192, 238, 191, 237), (0, 191, 237, 191, 97), (0, 191, 97, 192, 96), (0, 192, 96, 192, 95), (0, 37, 39, 38, 38), (0, 38, 38, 192, 38), (0, 192, 38, 193, 39), (0, 193, 39, 193, 94), (0, 193, 94, 192, 95), (0, 192, 95, 192, 96), (0, 192, 96, 191, 97), (0, 191, 97, 154, 97), (0, 154, 97, 153, 98), (0, 153, 98, 129, 98), (0,129, 98, 127, 96), (0, 127, 96, 102, 96), (0, 102, 96, 101, 97), (0, 101, 97, 47, 97), (0, 47, 97, 45, 99), (0, 45, 99, 38, 99), (0, 38, 99, 37, 98), (0, 37, 98, 37, 39), (0, 38, 38, 37, 39), (0, 37, 39, 37, 98), (0, 37, 98, 38, 99), (0, 38, 99, 43, 99), (0, 43, 99, 44, 100), (0, 44, 100, 44, 280), (0, 44, 280, 46, 282), (0, 46, 282, 46, 283), (0, 46, 283, 45, 284), (0, 45, 284, 45, 288), (0, 45, 288, 46, 289), (0, 46, 289, 192, 289), (0, 192, 289, 194, 291), (0, 194, 291, 194, 293), (0, 194, 293, 195, 294), (0, 195, 294, 195, 312), (0, 195, 312, 194, 313), (0, 194, 313, 194, 314), (0, 194, 314, 193, 315), (0, 193, 315, 193, 481), (0, 193, 481, 195, 483), (0, 195, 483, 334, 483), (0, 334, 483, 339, 488), (0, 339, 488, 334, 483), (0, 334, 483, 334, 96), (0, 334, 96, 332, 94), (0, 332, 94, 194, 94), (0, 194, 94, 193, 93), (0, 193, 93, 193, 39), (0, 193, 39, 192, 38), (0, 192, 38, 38, 38)]
    door_data = [(1, 204, 287, 205, 286), (1, 205, 286, 230, 286), (1, 230, 286, 231, 287), (1, 231, 287, 231, 295), (1, 231, 295, 230, 296), (1, 230, 296, 230, 299), (1, 230, 299, 229, 300), (1, 229, 300, 229, 301), (1, 229, 301, 228, 302), (1, 228, 302, 228, 303), (1, 228, 303, 226, 305), (1, 226, 305, 226, 306), (1, 226, 306, 219, 313), (1, 219, 313, 218, 313), (1, 218, 313, 216, 315), (1, 216, 315, 215, 315), (1, 215, 315, 214, 316), (1, 214, 316, 212, 316), (1, 212, 316, 211, 317), (1, 211, 317, 204, 317), (1, 204, 317, 203, 316), (1, 203, 316, 203, 290), (1, 203, 290, 204, 289), (1, 204, 289, 204, 287), (1, 205, 286, 204, 287), (1, 204, 287, 204, 289), (1, 204, 289, 203, 290), (1, 203, 290, 203, 316), (1, 203, 316, 204, 317), (1, 204, 317, 211, 317), (1, 211, 317, 212, 316), (1, 212, 316, 214, 316), (1, 214, 316, 215, 315), (1, 215, 315, 216, 315), (1, 216, 315, 218, 313), (1, 218, 313, 219, 313), (1, 219, 313, 226, 306), (1, 226, 306, 226, 305), (1, 226, 305, 228, 303), (1, 228, 303, 228, 302), (1, 228, 302, 229, 301), (1, 229, 301, 229, 300), (1, 229, 300, 230, 299), (1, 230, 299, 230, 296), (1, 230, 296, 231, 295), (1, 231, 295, 231, 287), (1, 231, 287, 230, 286), (1, 230, 286, 205, 286), (1, 46, 249, 47, 248), (1, 47, 248, 52, 248), (1, 52, 248, 53, 249), (1, 53, 249, 55, 249), (1, 55, 249, 56, 250), (1, 56, 250, 57, 250), (1, 57, 250, 58, 251), (1, 58, 251, 59, 251), (1, 59, 251, 60, 252), (1, 60, 252, 61, 252), (1, 61, 252, 64, 255), (1, 64, 255, 65, 255), (1, 65, 255, 69, 259), (1, 69, 259, 69, 260), (1, 69, 260, 71, 262), (1, 71, 262, 71, 263), (1, 71, 263, 72, 264), (1, 72, 264, 72, 265), (1, 72, 265, 73, 266), (1, 73, 266, 73, 267), (1, 73, 267, 74, 268), (1, 74, 268, 74, 275), (1, 74, 275, 73, 276), (1, 73, 276, 44, 276), (1, 44, 276, 43, 275), (1, 43, 275, 43, 250), (1, 43, 250, 44, 249), (1, 44, 249, 46, 249), (1, 47, 248, 46, 249), (1, 46, 249, 44, 249), (1, 44, 249, 43, 250), (1, 43, 250, 43, 275), (1, 43, 275, 44, 276), (1, 44, 276, 73, 276), (1, 73, 276, 74, 275), (1, 74, 275, 74, 268), (1, 74, 268, 73, 267), (1, 73, 267, 73, 266), (1, 73, 266, 72, 265), (1, 72, 265, 72, 264), (1, 72, 264, 71, 263), (1, 71, 263, 71, 262), (1, 71, 262, 69, 260), (1, 69, 260, 69, 259), (1, 69, 259, 65, 255), (1, 65, 255, 64, 255), (1, 64, 255, 61, 252), (1, 61, 252, 60, 252), (1, 60, 252, 59, 251), (1, 59, 251, 58, 251), (1, 58, 251, 57, 250), (1, 57, 250, 56, 250), (1, 56, 250, 55, 249), (1, 55, 249, 53, 249), (1, 53, 249, 52, 248), (1, 52, 248, 47, 248), (1, 203, 209, 204, 208), (1, 204, 208, 209, 208), (1, 209, 208, 210, 209), (1, 210, 209, 212, 209), (1, 212, 209, 213, 210), (1, 213, 210, 214, 210), (1, 214, 210, 215, 211), (1, 215, 211, 216, 211), (1, 216, 211, 218, 213), (1, 218, 213, 219, 213), (1, 219, 213, 226, 220), (1, 226, 220, 226, 221), (1, 226, 221, 228, 223), (1, 228, 223, 228, 224), (1, 228, 224, 229, 225), (1, 229, 225, 229, 226), (1, 229, 226, 230, 227), (1, 230, 227, 230, 230), (1, 230, 230, 231, 231), (1, 231, 231, 231, 236), (1, 231, 236, 230, 237), (1, 230, 237, 204, 237), (1, 204, 237, 203, 236), (1, 203, 236, 203, 209), (1, 204, 208, 203, 209), (1, 203, 209, 203, 236), (1, 203, 236, 204, 237), (1, 204, 237, 230, 237), (1, 230, 237, 231, 236), (1, 231, 236, 231, 231), (1, 231, 231, 230, 230), (1, 230, 230, 230, 227), (1, 230, 227, 229, 226), (1, 229, 226, 229, 225), (1, 229, 225, 228, 224), (1, 228, 224, 228, 223), (1, 228, 223, 226, 221), (1, 226, 221, 226, 220), (1, 226, 220, 219, 213), (1, 219, 213, 218, 213), (1, 218, 213, 216, 211), (1, 216, 211, 215, 211), (1, 215, 211, 214, 210), (1, 214, 210, 213, 210), (1, 213, 210, 212, 209), (1, 212, 209, 210, 209), (1, 210, 209, 209, 208), (1, 209, 208, 204, 208)]
    
    # 1. 入参是真实的户型图： https://ke-image.ljcdn.com/hdic-frame/standard_96bd87f6-d5fd-4fa0-b300-d96ed7cb0c89.png.1440x1080.jpg?from=ke.com
    # ->
    # https://ke-image.ljcdn.com/hdic-frame/standard_xxx.png.1000x750.jpg?from=ke.com
    # https://vrlab-public.ljcdn.com/release/vrcustomer/hierarchy_0_xxx.png
    # 返回todo: url 获取 线框坐标all_data， 墙是0，门是1，窗户是3
    all_data = xy_bboxes + door_data
    # 2. 入参是真实的户型图： https://ke-image.ljcdn.com/hdic-frame/standard_96bd87f6-d5fd-4fa0-b300-d96ed7cb0c89.png.1440x1080.jpg?from=ke.com
    # 返回todo: 获取比例信息 radio_wall， [min_x,min_y,max_x,max_y],[w,h]


    radio_wall = 24.6767
    # radio_wall = 1

    fl_img_dc = FloorplanImageDataConverter()
    fl_img_dc.showImg(door_data,[])
    fl_img_dc.showImg(xy_bboxes,[]) 
    # 入参 坐标点数据，比例因子
    x_data,y_data = fl_img_dc.run(all_data, radio_wall, [])
    fl_img_dc.showImg(x_data,y_data,False)
    
    # 转换
    data_c = (x_data + y_data)

    from KeFloorplanConverter import KeFloorplanConverter

    keFloorplanConverter = KeFloorplanConverter()
     # 入参 坐标点数据
    mangoDict = keFloorplanConverter.run(data_c)
    print(json.dumps(mangoDict, ensure_ascii=False))

    #  最终返回 mangoDict,[min_x,min_y,max_x,max_y],[w,h]


    # output = json.dumps(mangoDict, ensure_ascii=False)
    # chunk_size = 1000
    # for i in range(0, len(output), chunk_size):
    #     print(output[i:i+chunk_size])